mirror of https://github.com/AMT-Cheif/drift.git
Support table-valued json1 functions
This commit is contained in:
parent
5268d88344
commit
71ef9b8cd7
|
@ -13,8 +13,6 @@ abstract class Column
|
|||
/// Some columns, notably the rowid aliases, are exempt from this.
|
||||
bool get includedInResults => true;
|
||||
|
||||
Column();
|
||||
|
||||
@override
|
||||
String humanReadableDescription() {
|
||||
return name;
|
||||
|
|
|
@ -24,6 +24,14 @@ abstract class ResultSet implements ResolvesToResultSet {
|
|||
}
|
||||
}
|
||||
|
||||
/// A custom result set that has columns but isn't a table.
|
||||
class CustomResultSet with ResultSet {
|
||||
@override
|
||||
final List<Column> resolvedColumns;
|
||||
|
||||
CustomResultSet(this.resolvedColumns);
|
||||
}
|
||||
|
||||
/// A database table. The information stored here will be used to resolve
|
||||
/// references and for type inference.
|
||||
class Table
|
||||
|
|
|
@ -5,7 +5,10 @@ class Json1Extension implements Extension {
|
|||
|
||||
@override
|
||||
void register(SqlEngine engine) {
|
||||
engine.registerFunctionHandler(const _Json1Functions());
|
||||
engine
|
||||
..registerFunctionHandler(const _Json1Functions())
|
||||
..registerTableValuedFunctionHandler(const _JsonEachFunction())
|
||||
..registerTableValuedFunctionHandler(const _JsonTreeFunction());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -68,3 +71,42 @@ class _Json1Functions implements FunctionHandler {
|
|||
@override
|
||||
void reportErrors(SqlInvocation call, AnalysisContext context) {}
|
||||
}
|
||||
|
||||
final _jsonFunctionResultSet = CustomResultSet([
|
||||
// https://www.sqlite.org/json1.html#the_json_each_and_json_tree_table_valued_functions
|
||||
// we use string for any
|
||||
TableColumn('key', const ResolvedType(type: BasicType.text)),
|
||||
TableColumn(
|
||||
'value', const ResolvedType(type: BasicType.text, nullable: true)),
|
||||
TableColumn('type', const ResolvedType(type: BasicType.text)),
|
||||
TableColumn('atom', const ResolvedType(type: BasicType.text)),
|
||||
TableColumn('type', const ResolvedType(type: BasicType.text)),
|
||||
TableColumn('id', const ResolvedType(type: BasicType.int)),
|
||||
TableColumn(
|
||||
'parent', const ResolvedType(type: BasicType.int, nullable: true)),
|
||||
TableColumn('fullkey', const ResolvedType(type: BasicType.text)),
|
||||
]);
|
||||
|
||||
abstract class _JsonTableValuedFunction implements TableValuedFunctionHandler {
|
||||
const _JsonTableValuedFunction();
|
||||
|
||||
@override
|
||||
ResultSet resolveTableValued(
|
||||
AnalysisContext context, TableValuedFunction call) {
|
||||
return _jsonFunctionResultSet;
|
||||
}
|
||||
}
|
||||
|
||||
class _JsonEachFunction extends _JsonTableValuedFunction {
|
||||
const _JsonEachFunction();
|
||||
|
||||
@override
|
||||
String get functionName => 'json_each';
|
||||
}
|
||||
|
||||
class _JsonTreeFunction extends _JsonTableValuedFunction {
|
||||
const _JsonTreeFunction();
|
||||
|
||||
@override
|
||||
String get functionName => 'json_tree';
|
||||
}
|
||||
|
|
|
@ -12,11 +12,18 @@ void main() {
|
|||
}
|
||||
|
||||
void _runTests(bool types2) {
|
||||
final engine = SqlEngine.withOptions(EngineOptions(
|
||||
enableExperimentalTypeInference: types2,
|
||||
enabledExtensions: const [Json1Extension()],
|
||||
));
|
||||
// add user (name, phone) table
|
||||
final table = engine.schemaReader.read(
|
||||
engine.parse('CREATE TABLE user (name TEXT, phone TEXT)').rootNode
|
||||
as TableInducingStatement,
|
||||
);
|
||||
engine.registerTable(table);
|
||||
|
||||
ResolveResult findResult(String expression) {
|
||||
final engine = SqlEngine.withOptions(EngineOptions(
|
||||
enableExperimentalTypeInference: types2,
|
||||
enabledExtensions: const [Json1Extension()],
|
||||
));
|
||||
final result = engine.analyze('SELECT $expression;');
|
||||
|
||||
final select = result.root as SelectStatement;
|
||||
|
@ -63,4 +70,14 @@ void _runTests(bool types2) {
|
|||
const ResolveResult(ResolvedType(type: BasicType.int)),
|
||||
);
|
||||
});
|
||||
|
||||
test('can use table-valued functions', () {
|
||||
final result = engine.analyze('''
|
||||
SELECT DISTINCT user.name
|
||||
FROM user, json_each(user.phone)
|
||||
WHERE json_each.value LIKE '704-%';
|
||||
''');
|
||||
|
||||
expect(result.errors, isEmpty);
|
||||
});
|
||||
}
|
Loading…
Reference in New Issue