mirror of https://github.com/AMT-Cheif/drift.git
166 lines
5.4 KiB
Dart
166 lines
5.4 KiB
Dart
import 'package:sqlparser/sqlparser.dart';
|
|
import 'package:test/test.dart';
|
|
|
|
final _fts5Options = EngineOptions(enabledExtensions: const [Fts5Extension()]);
|
|
|
|
void main() {
|
|
group('creating fts5 tables', () {
|
|
final engine = SqlEngine(_fts5Options);
|
|
|
|
test('can create fts5 tables', () {
|
|
final result = engine.analyze('CREATE VIRTUAL TABLE foo USING '
|
|
"fts5(bar , tokenize = 'porter ascii')");
|
|
|
|
final table =
|
|
SchemaFromCreateTable().read(result.root as TableInducingStatement);
|
|
|
|
expect(table.name, 'foo');
|
|
final columns = table.resultColumns;
|
|
expect(columns, hasLength(1));
|
|
expect(columns.single.name, 'bar');
|
|
});
|
|
|
|
test('handles the UNINDEXED column option', () {
|
|
final result = engine
|
|
.analyze('CREATE VIRTUAL TABLE foo USING fts5(bar, baz UNINDEXED)');
|
|
|
|
final table =
|
|
SchemaFromCreateTable().read(result.root as TableInducingStatement);
|
|
|
|
expect(table.name, 'foo');
|
|
expect(table.resultColumns.map((c) => c.name), ['bar', 'baz']);
|
|
});
|
|
});
|
|
|
|
group('type inference for function calls', () {
|
|
SqlEngine engine;
|
|
setUp(() {
|
|
engine = SqlEngine(_fts5Options);
|
|
// add an fts5 table for the following queries
|
|
final fts5Result = engine.analyze('CREATE VIRTUAL TABLE foo USING '
|
|
'fts5(bar, baz);');
|
|
engine.registerTable(SchemaFromCreateTable()
|
|
.read(fts5Result.root as TableInducingStatement));
|
|
});
|
|
|
|
test('return type of bm25()', () {
|
|
final result = engine
|
|
.analyze('SELECT *, bm25(foo) AS b FROM foo WHERE foo MATCH \'\'');
|
|
|
|
final select = result.root as SelectStatement;
|
|
final column = select.resolvedColumns.singleWhere((c) => c.name == 'b');
|
|
expect(result.typeOf(column),
|
|
const ResolveResult(ResolvedType(type: BasicType.real)));
|
|
});
|
|
|
|
test('return type of highlight()', () {
|
|
final result =
|
|
engine.analyze("SELECT *, highlight(foo, 0, '<b>', '</b>') AS b "
|
|
"FROM foo WHERE foo MATCH ''");
|
|
|
|
final select = result.root as SelectStatement;
|
|
final column = select.resolvedColumns.singleWhere((c) => c.name == 'b');
|
|
expect(result.typeOf(column),
|
|
const ResolveResult(ResolvedType(type: BasicType.text)));
|
|
});
|
|
|
|
test('return type of snippet()', () {
|
|
final result = engine
|
|
.analyze("SELECT *, snippet(foo, 0, '<b>', '</b>', '...', 20) AS b "
|
|
"FROM foo WHERE foo MATCH ''");
|
|
|
|
final select = result.root as SelectStatement;
|
|
final column = select.resolvedColumns.singleWhere((c) => c.name == 'b');
|
|
expect(result.typeOf(column),
|
|
const ResolveResult(ResolvedType(type: BasicType.text)));
|
|
});
|
|
});
|
|
|
|
group('type inference for function arguments', () {
|
|
SqlEngine engine;
|
|
setUp(() {
|
|
engine = SqlEngine(_fts5Options);
|
|
// add an fts5 table for the following queries
|
|
final fts5Result = engine.analyze('CREATE VIRTUAL TABLE foo USING '
|
|
'fts5(bar, baz);');
|
|
engine.registerTable(SchemaFromCreateTable()
|
|
.read(fts5Result.root as TableInducingStatement));
|
|
});
|
|
|
|
void checkVarTypes(String sql, List<BasicType> expected) {
|
|
final result = engine.analyze(sql);
|
|
final foundVars = result.root.allDescendants.whereType<Variable>();
|
|
|
|
expect(
|
|
foundVars.map((Typeable t) => result.typeOf(t).type.type),
|
|
expected,
|
|
);
|
|
}
|
|
|
|
test('for highlight()', () {
|
|
checkVarTypes(
|
|
'SELECT highlight(fts, ?, ?, ?) FROM fts;',
|
|
[
|
|
BasicType.int, // column index
|
|
BasicType.text, // text before phrase match
|
|
BasicType.text, // text after phrase match
|
|
],
|
|
);
|
|
});
|
|
|
|
test('for snippet()', () {
|
|
checkVarTypes(
|
|
'SELECT snippet(fts, ?, ?, ?, ?, ?) FROM fts;',
|
|
[
|
|
BasicType.int, // column index
|
|
BasicType.text, // text before match
|
|
BasicType.text, // text after match
|
|
BasicType.text, // text to add match isn't at start
|
|
BasicType.int, // maximum number of tokens
|
|
],
|
|
);
|
|
});
|
|
});
|
|
|
|
group('error reporting', () {
|
|
SqlEngine engine;
|
|
setUp(() {
|
|
engine = SqlEngine(_fts5Options);
|
|
// add an fts5 table for the following queries
|
|
final fts5Result = engine.analyze('CREATE VIRTUAL TABLE foo USING '
|
|
'fts5(bar, baz);');
|
|
engine.registerTable(SchemaFromCreateTable()
|
|
.read(fts5Result.root as TableInducingStatement));
|
|
|
|
final normalResult = engine.analyze('CREATE TABLE other (bar TEXT);');
|
|
engine.registerTable(SchemaFromCreateTable()
|
|
.read(normalResult.root as TableInducingStatement));
|
|
});
|
|
|
|
Matcher hasMessage(Object msgMatcher) {
|
|
return const TypeMatcher<AnalysisError>()
|
|
.having((e) => e.message, 'message', msgMatcher);
|
|
}
|
|
|
|
test('when using star function parameters', () {
|
|
final result = engine.analyze('SELECT bm25(*) FROM foo;');
|
|
expect(result.errors, [hasMessage(contains('star parameter'))]);
|
|
});
|
|
|
|
test('when using a non-fts5 table as parameter', () {
|
|
final result = engine.analyze('SELECT bm25(bar) FROM other');
|
|
expect(result.errors, [hasMessage(contains('fts5 table name'))]);
|
|
});
|
|
|
|
test('when using the wrong number or arguments', () {
|
|
final result = engine.analyze('SELECT highlight(foo, 3) FROM foo');
|
|
expect(
|
|
result.errors,
|
|
[
|
|
hasMessage(stringContainsInOrder(['highlight', '4', '2']))
|
|
],
|
|
);
|
|
});
|
|
});
|
|
}
|