mirror of https://github.com/AMT-Cheif/drift.git
Fix analyzer crash at CTE (#255)
This commit is contained in:
parent
a1f9e7ce13
commit
bb1fcc1590
|
@ -966,6 +966,13 @@ abstract class _$CustomTablesDb extends GeneratedDatabase {
|
|||
readsFrom: {config}).map(_rowToReadRowIdResult);
|
||||
}
|
||||
|
||||
Selectable<int> test() {
|
||||
return customSelectQuery(
|
||||
'WITH RECURSIVE\n cnt(x) AS (\n SELECT 1\n UNION ALL\n SELECT x+1 FROM cnt\n LIMIT 1000000\n )\n SELECT x FROM cnt',
|
||||
variables: [],
|
||||
readsFrom: {}).map((QueryRow row) => row.readInt('x'));
|
||||
}
|
||||
|
||||
Future<int> writeConfig(String key, String value) {
|
||||
return customInsert(
|
||||
'REPLACE INTO config VALUES (:key, :value)',
|
||||
|
|
|
@ -31,4 +31,13 @@ readConfig: SELECT * FROM config WHERE config_key = ?;
|
|||
readMultiple: SELECT * FROM config WHERE config_key IN ? ORDER BY $clause;
|
||||
readDynamic: SELECT * FROM config WHERE $predicate;
|
||||
|
||||
readRowId: SELECT oid, * FROM config WHERE _rowid_ = $expr;
|
||||
readRowId: SELECT oid, * FROM config WHERE _rowid_ = $expr;
|
||||
|
||||
cfeTest: WITH RECURSIVE
|
||||
cnt(x) AS (
|
||||
SELECT 1
|
||||
UNION ALL
|
||||
SELECT x+1 FROM cnt
|
||||
LIMIT 1000000
|
||||
)
|
||||
SELECT x FROM cnt;
|
|
@ -18,9 +18,9 @@ class ReferencedTablesVisitor extends RecursiveVisitor<void> {
|
|||
@override
|
||||
void visitQueryable(Queryable e) {
|
||||
if (e is TableReference) {
|
||||
final table = e.resolved as Table;
|
||||
if (table != null) {
|
||||
foundTables.add(table);
|
||||
final resolved = e.resolved;
|
||||
if (resolved != null && resolved is Table) {
|
||||
foundTables.add(resolved);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -156,8 +156,13 @@ class QueryHandler {
|
|||
} else if (c is ExpressionColumn) {
|
||||
final expression = c.expression;
|
||||
if (expression is Reference) {
|
||||
return expression.resolved as TableColumn;
|
||||
final resolved = expression.resolved;
|
||||
if (resolved is Column) {
|
||||
return _toTableColumn(resolved);
|
||||
}
|
||||
}
|
||||
} else if (c is DelegatedColumn) {
|
||||
return _toTableColumn(c.innerColumn);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
|
|
@ -0,0 +1,66 @@
|
|||
import 'package:build/build.dart';
|
||||
import 'package:moor_generator/src/analyzer/runner/file_graph.dart';
|
||||
import 'package:moor_generator/src/analyzer/runner/results.dart';
|
||||
import 'package:moor_generator/src/analyzer/runner/task.dart';
|
||||
import 'package:moor_generator/src/analyzer/session.dart';
|
||||
import 'package:moor_generator/src/model/specified_column.dart';
|
||||
import 'package:moor_generator/src/model/sql_query.dart';
|
||||
import 'package:test/test.dart';
|
||||
|
||||
import '../../utils/test_backend.dart';
|
||||
|
||||
void main() {
|
||||
TestBackend backend;
|
||||
MoorSession session;
|
||||
Task task;
|
||||
|
||||
setUpAll(() {
|
||||
backend = TestBackend(
|
||||
{
|
||||
AssetId.parse('foo|lib/test.moor'): r'''
|
||||
test:
|
||||
WITH RECURSIVE
|
||||
cnt(x) AS (
|
||||
SELECT 1
|
||||
UNION ALL
|
||||
SELECT x+1 FROM cnt
|
||||
LIMIT 1000000
|
||||
)
|
||||
SELECT x FROM cnt;
|
||||
''',
|
||||
},
|
||||
);
|
||||
session = backend.session;
|
||||
});
|
||||
|
||||
setUp(() async {
|
||||
final backendTask = backend.startTask(Uri.parse('package:foo/test.moor'));
|
||||
task = session.startTask(backendTask);
|
||||
await task.runTask();
|
||||
});
|
||||
|
||||
tearDownAll(() {
|
||||
backend.finish();
|
||||
});
|
||||
|
||||
test('recognizes CFE clause', () {
|
||||
final file = session.registerFile(Uri.parse('package:foo/test.moor'));
|
||||
|
||||
expect(file.state, FileState.analyzed);
|
||||
expect(file.errors.errors, isEmpty);
|
||||
|
||||
final result = file.currentResult as ParsedMoorFile;
|
||||
final query = result.resolvedQueries.single as SqlSelectQuery;
|
||||
|
||||
expect(query.name, 'test');
|
||||
expect(query.variables, isEmpty);
|
||||
expect(query.declaredInMoorFile, isTrue);
|
||||
expect(query.readsFrom, isEmpty);
|
||||
|
||||
final resultSet = query.resultSet;
|
||||
expect(resultSet.singleColumn, isTrue);
|
||||
expect(resultSet.needsOwnClass, isFalse);
|
||||
expect(resultSet.columns.map(resultSet.dartNameFor), ['x']);
|
||||
expect(resultSet.columns.map((c) => c.type), [ColumnType.integer]);
|
||||
});
|
||||
}
|
|
@ -31,6 +31,10 @@ abstract class TableOrSubquery extends Queryable {}
|
|||
///
|
||||
/// This is both referencable (if we have SELECT * FROM table t), other parts
|
||||
/// of the select statement can access "t") and a reference owner (the table).
|
||||
///
|
||||
/// Note that this doesn't necessarily resolve to a result set. It could also
|
||||
/// resolve to a common table expression or anything else defining a result
|
||||
/// set.
|
||||
class TableReference extends TableOrSubquery
|
||||
with ReferenceOwner
|
||||
implements Renamable, ResolvesToResultSet, VisibleToChildren {
|
||||
|
|
|
@ -55,8 +55,10 @@ void main() {
|
|||
|
||||
expect(context.errors, isEmpty);
|
||||
final select = context.root as SelectStatement;
|
||||
final column = context.typeOf(select.resolvedColumns.single);
|
||||
final column = select.resolvedColumns.single;
|
||||
final type = context.typeOf(column);
|
||||
|
||||
expect(column.type, const ResolvedType(type: BasicType.int));
|
||||
expect(type.type, const ResolvedType(type: BasicType.int));
|
||||
expect(column.name, 'x');
|
||||
});
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue