mirror of https://github.com/AMT-Cheif/drift.git
added rtree support
This commit is contained in:
parent
c44578da60
commit
d1e623a0c6
|
@ -275,4 +275,8 @@ enum SqlModule {
|
|||
///
|
||||
/// [math funs]: https://www.sqlite.org/lang_mathfunc.html
|
||||
math,
|
||||
|
||||
/// Enables support for the rtree module and its functions when parsing sql
|
||||
/// queries.
|
||||
rtree,
|
||||
}
|
||||
|
|
|
@ -140,6 +140,7 @@ const _$SqlModuleEnumMap = {
|
|||
SqlModule.fts5: 'fts5',
|
||||
SqlModule.moor_ffi: 'moor_ffi',
|
||||
SqlModule.math: 'math',
|
||||
SqlModule.rtree: 'rtree',
|
||||
};
|
||||
|
||||
DialectOptions _$DialectOptionsFromJson(Map json) => $checkedCreate(
|
||||
|
|
|
@ -45,6 +45,7 @@ class MoorSession {
|
|||
if (options.hasModule(SqlModule.json1)) const Json1Extension(),
|
||||
if (options.hasModule(SqlModule.moor_ffi)) const MoorFfiExtension(),
|
||||
if (options.hasModule(SqlModule.math)) const BuiltInMathExtension(),
|
||||
if (options.hasModule(SqlModule.rtree)) const RTreeExtension(),
|
||||
],
|
||||
version: options.sqliteVersion,
|
||||
);
|
||||
|
|
|
@ -7,6 +7,7 @@ export 'src/ast/ast.dart';
|
|||
export 'src/engine/module/fts5.dart' show Fts5Extension;
|
||||
export 'src/engine/module/json1.dart' show Json1Extension;
|
||||
export 'src/engine/module/math.dart' show BuiltInMathExtension;
|
||||
export 'src/engine/module/rtree.dart' show RTreeExtension;
|
||||
export 'src/engine/module/module.dart';
|
||||
export 'src/engine/options.dart';
|
||||
export 'src/engine/sql_engine.dart';
|
||||
|
|
|
@ -0,0 +1,39 @@
|
|||
import 'package:sqlparser/sqlparser.dart';
|
||||
|
||||
class RTreeExtension implements Extension {
|
||||
const RTreeExtension();
|
||||
|
||||
@override
|
||||
void register(SqlEngine engine) {
|
||||
engine.registerModule(_RTreeModule());
|
||||
}
|
||||
}
|
||||
|
||||
class _RTreeModule extends Module {
|
||||
_RTreeModule() : super('rtree');
|
||||
|
||||
@override
|
||||
Table parseTable(CreateVirtualTableStatement stmt) {
|
||||
final columnNames = stmt.argumentContent;
|
||||
|
||||
if (columnNames.length < 3 || columnNames.length > 11) {
|
||||
throw ArgumentError(
|
||||
'An rtree virtual table is supposed to have between 3 and 11 columns');
|
||||
}
|
||||
|
||||
if (columnNames.length.isEven) {
|
||||
throw ArgumentError(
|
||||
'The rtree has not been initialized with a proper dimension. '
|
||||
'Required is an index, follwoed by a even number of min/max pairs');
|
||||
}
|
||||
|
||||
return Table(name: stmt.tableName, resolvedColumns: [
|
||||
for (final columnName in columnNames)
|
||||
//First column is always an integer primary key
|
||||
//followed by n floating point values
|
||||
(columnName == columnNames.first)
|
||||
? TableColumn(columnName, const ResolvedType(type: BasicType.int))
|
||||
: TableColumn(columnName, const ResolvedType(type: BasicType.real))
|
||||
]);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,65 @@
|
|||
import 'package:sqlparser/sqlparser.dart';
|
||||
import 'package:test/test.dart';
|
||||
|
||||
final _rtreeOptions =
|
||||
EngineOptions(enabledExtensions: const [RTreeExtension()]);
|
||||
|
||||
void main() {
|
||||
group('creating rtree tables', () {
|
||||
final engine = SqlEngine(_rtreeOptions);
|
||||
|
||||
test('can create rtree table', () {
|
||||
final result = engine.analyze('''
|
||||
CREATE VIRTUAL TABLE demo_index USING rtree(
|
||||
id, -- Integer primary key
|
||||
minX, maxX, -- Minimum and maximum X coordinate
|
||||
minY, maxY -- Minimum and maximum Y coordinate
|
||||
);''');
|
||||
|
||||
final table = const SchemaFromCreateTable()
|
||||
.read(result.root as TableInducingStatement);
|
||||
|
||||
expect(table.name, 'demo_index');
|
||||
final columns = table.resultColumns;
|
||||
expect(columns, hasLength(5));
|
||||
expect(columns.first.type.type, equals(BasicType.int));
|
||||
expect(columns.last.type.type, equals(BasicType.real));
|
||||
});
|
||||
});
|
||||
|
||||
group('type inference for function arguments', () {
|
||||
late SqlEngine engine;
|
||||
setUp(() {
|
||||
engine = SqlEngine(_rtreeOptions);
|
||||
// add an fts5 table for the following queries
|
||||
final result = engine.analyze('''
|
||||
CREATE VIRTUAL TABLE demo_index USING rtree(
|
||||
id, -- Integer primary key
|
||||
minX, maxX, -- Minimum and maximum X coordinate
|
||||
minY, maxY -- Minimum and maximum Y coordinate
|
||||
);''');
|
||||
|
||||
engine.registerTable(const SchemaFromCreateTable()
|
||||
.read(result.root as TableInducingStatement));
|
||||
});
|
||||
|
||||
test('insert', () {
|
||||
final result = engine.analyze('INSERT INTO demo_index VALUES '
|
||||
'(28215, -80.781227, -80.604706, 35.208813, 35.297367);');
|
||||
expect(result.errors, isEmpty);
|
||||
});
|
||||
|
||||
test('select', () {
|
||||
final result = engine.analyze('''
|
||||
SELECT A.* FROM demo_index AS A, demo_index AS B
|
||||
WHERE A.maxX>=B.minX AND A.minX<=B.maxX
|
||||
AND A.maxY>=B.minY AND A.minY<=B.maxY
|
||||
AND B.id=28269;''');
|
||||
|
||||
final columns = (result.root as SelectStatement).resolvedColumns;
|
||||
|
||||
expect(result.errors, isEmpty);
|
||||
expect(columns, hasLength(5));
|
||||
});
|
||||
});
|
||||
}
|
Loading…
Reference in New Issue