diff --git a/sqlparser/CHANGELOG.md b/sqlparser/CHANGELOG.md index 8ff087b84..0377d99a3 100644 --- a/sqlparser/CHANGELOG.md +++ b/sqlparser/CHANGELOG.md @@ -1,3 +1,7 @@ +## 0.39.2-dev + +- Fix false-positive lint for a parameter count mismatch on `bm25()`. + ## 0.39.1 - Improve recovery in parser when encountering syntax errors. diff --git a/sqlparser/lib/src/engine/module/fts5.dart b/sqlparser/lib/src/engine/module/fts5.dart index deb5f6f2f..a84954a86 100644 --- a/sqlparser/lib/src/engine/module/fts5.dart +++ b/sqlparser/lib/src/engine/module/fts5.dart @@ -153,8 +153,13 @@ class _Fts5Functions with ArgumentCountLinter implements FunctionHandler { switch (call.name) { case 'bm25': - // bm25(fts_table) - return const ResolveResult.unknown(); + // bm25(fts_table, weights...) + if (argumentIndex == 0) { + return const ResolveResult.unknown(); + } else { + return const ResolveResult(ResolvedType(type: BasicType.int)); + } + case 'highlight': // highlight(fts_table, column_index, text_before, text_after) if (argumentIndex == 1) { @@ -183,7 +188,6 @@ class _Fts5Functions with ArgumentCountLinter implements FunctionHandler { case 'bm25': return const ResolveResult(ResolvedType(type: BasicType.real)); case 'highlight': - return const ResolveResult(ResolvedType(type: BasicType.text)); case 'snippet': return const ResolveResult(ResolvedType(type: BasicType.text)); } @@ -193,7 +197,6 @@ class _Fts5Functions with ArgumentCountLinter implements FunctionHandler { @override int? argumentCountFor(String function) { return const { - 'bm25': 1, 'highlight': 4, 'snippet': 6, }[function]; @@ -212,9 +215,10 @@ class _Fts5Functions with ArgumentCountLinter implements FunctionHandler { } final args = (call.parameters as ExprFunctionParameters).parameters; - final expectedArgCount = argumentCountFor(call.name.toLowerCase()); + final calledFunction = call.name.toLowerCase(); + final expectedArgCount = argumentCountFor(calledFunction); - if (expectedArgCount != args.length) { + if (expectedArgCount != null && expectedArgCount != args.length) { reportArgumentCountMismatch(call, context, expectedArgCount, args.length); return; } @@ -231,6 +235,20 @@ class _Fts5Functions with ArgumentCountLinter implements FunctionHandler { message: 'Expected an fts5 table name here', type: AnalysisErrorType.other, )); + } else if (calledFunction == 'bm25') { + // The bm25 function can use (table, weights...) parameters, but there + // shouldn't be more weights than columns. + final source = firstResolved.source as _Fts5TableColumn; + if (source.table case final table?) { + if (args.length > table.resultColumns.length + 1) { + context.reportError(AnalysisError( + relevantNode: call, + message: 'Superfluous weight columns (there are only ' + '${table.resultColumns.length} columns on the table).', + type: AnalysisErrorType.other, + )); + } + } } } } diff --git a/sqlparser/pubspec.yaml b/sqlparser/pubspec.yaml index eaf8ba23f..c77d7a9ef 100644 --- a/sqlparser/pubspec.yaml +++ b/sqlparser/pubspec.yaml @@ -1,6 +1,6 @@ name: sqlparser description: Parses sqlite statements and performs static analysis on them -version: 0.39.1 +version: 0.39.2 homepage: https://github.com/simolus3/drift/tree/develop/sqlparser repository: https://github.com/simolus3/drift #homepage: https://drift.simonbinder.eu/ diff --git a/sqlparser/test/engine/module/fts5_test.dart b/sqlparser/test/engine/module/fts5_test.dart index 589232e51..79408534d 100644 --- a/sqlparser/test/engine/module/fts5_test.dart +++ b/sqlparser/test/engine/module/fts5_test.dart @@ -240,6 +240,16 @@ void main() { ], ); }); + + test('for bm25', () { + checkVarTypes( + 'SELECT bm25(fts, ?, ?) FROM fts;', + [ + BasicType.int, + BasicType.int, + ], + ); + }); }); group('error reporting', () { @@ -281,6 +291,19 @@ void main() { ], ); }); + + test('with too many weights in bm25', () { + final result = + engine.analyze('SELECT bm25(foo, 0.5, 0.6, 0.1) FROM foo;'); + + expect( + result.errors, + [ + hasMessage( + 'Superfluous weight columns (there are only 2 columns on the table).') + ], + ); + }); }); test('does not include rank and table columns in result', () {