Fix column references in subquery (#1894)

This commit is contained in:
Simon Binder 2022-06-17 18:17:42 +02:00
parent 4af9aed190
commit 81c59c0b99
No known key found for this signature in database
GPG Key ID: 7891917E4147B8C0
3 changed files with 39 additions and 1 deletions

View File

@ -22,6 +22,10 @@ class _ExistsExpression<T> extends Expression<bool> {
@override
void writeInto(GenerationContext context) {
final outerHasMultipleTables = context.hasMultipleTables;
// Inside this subquery, we want to reference columns with their table
// to avoid ambiguities when an outer table is referenced.
context.hasMultipleTables = true;
if (_not) {
context.buffer.write('NOT ');
}
@ -30,6 +34,7 @@ class _ExistsExpression<T> extends Expression<bool> {
context.buffer.write('(');
_select.writeInto(context);
context.buffer.write(')');
context.hasMultipleTables = outerHasMultipleTables;
}
@override

View File

@ -13,7 +13,7 @@ void main() {
expect(
existsExpression,
generates('EXISTS (SELECT * FROM users WHERE is_awesome = ?)', [1]),
generates('EXISTS (SELECT * FROM users WHERE users.is_awesome = ?)', [1]),
);
});

View File

@ -0,0 +1,33 @@
import 'package:drift/drift.dart';
import 'package:test/test.dart';
import '../generated/todos.dart';
import '../test_utils/test_utils.dart';
void main() {
test('exists subqueries properly reference columns', () async {
final db = TodoDb.connect(testInMemoryDatabase());
addTearDown(db.close);
final nonEmptyId = await db.categories
.insertOne(CategoriesCompanion.insert(description: 'category'));
await db.todosTable.insertOne(TodosTableCompanion.insert(
content: 'entry', category: Value(nonEmptyId)));
final emptyId = await db.categories.insertOne(
CategoriesCompanion.insert(description: 'this category empty YEET'));
final emptyCategories = await db.emptyCategories();
expect(emptyCategories, hasLength(1));
expect(emptyCategories.single.id, emptyId);
});
}
extension on TodoDb {
Future<List<Category>> emptyCategories() {
final hasNoTodo = notExistsQuery(select(todosTable)
..where((row) => row.category.equalsExp(categories.id)));
return (select(categories)..where((row) => hasNoTodo)).get();
}
}