Skip to content

Commit

Permalink
Propagate types with known nullability first
Browse files Browse the repository at this point in the history
Closes #3351
  • Loading branch information
simolus3 committed Nov 22, 2024
1 parent 06fdbd7 commit bf4a534
Show file tree
Hide file tree
Showing 4 changed files with 22 additions and 0 deletions.
2 changes: 2 additions & 0 deletions sqlparser/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
## 0.40.0-dev

- Add support for the `dbstat` module.
- Prioritize null propagation in type resolver, leading to more accurate
analysis on which columns are nullable.

## 0.39.2

Expand Down
4 changes: 4 additions & 0 deletions sqlparser/lib/src/analysis/types/graph/type_graph.dart
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,9 @@ class TypeGraph {
_indexRelations();

var queue = List.of(_knownTypes.keys);
// Apply type propagation to known types for which we know the nullability
// too first.
queue.sortBy<num>((e) => _knownNullability.containsKey(e) ? 1 : 0);
while (queue.isNotEmpty) {
_propagateTypeInfo(queue, queue.removeLast());
}
Expand Down Expand Up @@ -153,6 +156,7 @@ class TypeGraph {
.any((nullable) => nullable == true);

_knownNullability[edge.target] = nullable;
resolved.add(edge.target);
}
}

Expand Down
1 change: 1 addition & 0 deletions sqlparser/lib/src/analysis/types/types.dart
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import 'dart:math';

import 'package:collection/collection.dart';
import 'package:sqlparser/sqlparser.dart';

part 'expectation.dart';
Expand Down
15 changes: 15 additions & 0 deletions sqlparser/test/analysis/types2/misc_cases_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -176,4 +176,19 @@ WITH RECURSIVE
ResolvedType(type: BasicType.int),
]);
});

test('keeps nullability information across unions', () {
// https://github.com/simolus3/drift/issues/3351
final engine = SqlEngine();
final ctx = engine.analyze('''
SELECT CAST(NULL AS INT) AS value
UNION
SELECT CAST(NULL AS INT);
''');

final select = ctx.root as CompoundSelectStatement;
final column = select.resolvedColumns!.first;
expect(ctx.typeOf(column),
ResolveResult(ResolvedType(nullable: true, type: BasicType.int)));
});
}

0 comments on commit bf4a534

Please sign in to comment.