mirror of https://github.com/AMT-Cheif/drift.git
Fix issues with new inference, enable it by default
This commit is contained in:
parent
49f7dc059f
commit
9a78604d98
|
@ -7,6 +7,7 @@ analyzer:
|
||||||
unused_local_variable: error
|
unused_local_variable: error
|
||||||
dead_code: error
|
dead_code: error
|
||||||
public_member_api_docs: ignore # turned on by user-facing subpackages
|
public_member_api_docs: ignore # turned on by user-facing subpackages
|
||||||
|
deprecated_member_use_from_same_package: ignore
|
||||||
exclude:
|
exclude:
|
||||||
- "**/*.g.dart"
|
- "**/*.g.dart"
|
||||||
# Will be analyzed anyway, nobody knows why ¯\_(ツ)_/¯. We're only analyzing lib/ and test/ as a workaround
|
# Will be analyzed anyway, nobody knows why ¯\_(ツ)_/¯. We're only analyzing lib/ and test/ as a workaround
|
||||||
|
|
|
@ -52,19 +52,14 @@ At the moment, moor supports these options:
|
||||||
column constraint (e.g. `user_name VARCHAR NOT NULL JSON KEY userName`)
|
column constraint (e.g. `user_name VARCHAR NOT NULL JSON KEY userName`)
|
||||||
* `generate_connect_constructor`: Generate necessary code to support the [isolate runtime]({{< relref "isolates.md" >}}).
|
* `generate_connect_constructor`: Generate necessary code to support the [isolate runtime]({{< relref "isolates.md" >}}).
|
||||||
This is a build option because isolates are still experimental. This will be the default option eventually.
|
This is a build option because isolates are still experimental. This will be the default option eventually.
|
||||||
* `use_experimental_inference`: Use a new, experimental type inference algorithm when analyzing sql statements. The
|
|
||||||
algorithm is designed to yield more accurate results on nullability and complex constructs. Note that it's in a
|
|
||||||
preview state at the moment, which means that generated code might change after a minor update.
|
|
||||||
* `sqlite_modules`: This list can be used to enable sqlite extensions, like those for json or full-text search.
|
* `sqlite_modules`: This list can be used to enable sqlite extensions, like those for json or full-text search.
|
||||||
Modules have to be enabled explicitly because they're not supported on all platforms. See the following section for
|
Modules have to be enabled explicitly because they're not supported on all platforms. See the following section for
|
||||||
details.
|
details.
|
||||||
* `use_experimental_inference`: Enables a new type inference algorithm for sql statements.
|
|
||||||
The new algorithm is much better at handling complex statements and nullability.
|
|
||||||
However, it's still in development and may not work in all cases yet. Please report any issues you can find.
|
|
||||||
__Warning:__ The new type inference algorithm is in development and does not obey to semantic versioning.
|
|
||||||
Results and generated code might change in moor versions not declared as breaking.
|
|
||||||
* `eagerly_load_dart_ast`: Moor's builder will load the resolved AST whenever it encounters a Dart file,
|
* `eagerly_load_dart_ast`: Moor's builder will load the resolved AST whenever it encounters a Dart file,
|
||||||
instead of lazily when it reads a table. This is used to investigate rare builder crashes.
|
instead of lazily when it reads a table. This is used to investigate rare builder crashes.
|
||||||
|
* `legacy_type_inference`: Use the old type inference from moor 1 and 2. Note that `use_experimental_inference`
|
||||||
|
is now the default and no longer exists.
|
||||||
|
If you're using this flag, please open an issue and explain how the new inference isn't working for you, thanks!
|
||||||
|
|
||||||
## Available extensions
|
## Available extensions
|
||||||
|
|
||||||
|
|
|
@ -8,7 +8,6 @@ targets:
|
||||||
generate_connect_constructor: true
|
generate_connect_constructor: true
|
||||||
compact_query_methods: true
|
compact_query_methods: true
|
||||||
write_from_json_string_constructor: true
|
write_from_json_string_constructor: true
|
||||||
use_experimental_inference: true
|
|
||||||
eagerly_load_dart_ast: true
|
eagerly_load_dart_ast: true
|
||||||
sqlite_modules:
|
sqlite_modules:
|
||||||
- json1
|
- json1
|
||||||
|
|
|
@ -54,11 +54,10 @@ class MoorOptions {
|
||||||
@JsonKey(name: 'generate_connect_constructor', defaultValue: false)
|
@JsonKey(name: 'generate_connect_constructor', defaultValue: false)
|
||||||
final bool generateConnectConstructor;
|
final bool generateConnectConstructor;
|
||||||
|
|
||||||
/// Whether the new, experimental type inference engine should be used.
|
/// Whether the old, legacy type inference engine should be used when
|
||||||
///
|
/// analyzing custom sql queries.
|
||||||
/// The new engine is experimental at the moment.
|
@JsonKey(name: 'legacy_type_inference', defaultValue: false)
|
||||||
@JsonKey(name: 'use_experimental_inference', defaultValue: false)
|
final bool legacyTypeInference;
|
||||||
final bool useExperimentalInference;
|
|
||||||
|
|
||||||
@JsonKey(name: 'sqlite_modules', defaultValue: [])
|
@JsonKey(name: 'sqlite_modules', defaultValue: [])
|
||||||
final List<SqlModule> modules;
|
final List<SqlModule> modules;
|
||||||
|
@ -77,7 +76,7 @@ class MoorOptions {
|
||||||
this.useDataClassNameForCompanions = false,
|
this.useDataClassNameForCompanions = false,
|
||||||
this.useColumnNameAsJsonKeyWhenDefinedInMoorFile = false,
|
this.useColumnNameAsJsonKeyWhenDefinedInMoorFile = false,
|
||||||
this.generateConnectConstructor = false,
|
this.generateConnectConstructor = false,
|
||||||
this.useExperimentalInference = false,
|
this.legacyTypeInference = false,
|
||||||
this.eagerlyLoadDartAst = false,
|
this.eagerlyLoadDartAst = false,
|
||||||
this.modules = const []});
|
this.modules = const []});
|
||||||
|
|
||||||
|
|
|
@ -16,7 +16,7 @@ MoorOptions _$MoorOptionsFromJson(Map<String, dynamic> json) {
|
||||||
'use_data_class_name_for_companions',
|
'use_data_class_name_for_companions',
|
||||||
'use_column_name_as_json_key_when_defined_in_moor_file',
|
'use_column_name_as_json_key_when_defined_in_moor_file',
|
||||||
'generate_connect_constructor',
|
'generate_connect_constructor',
|
||||||
'use_experimental_inference',
|
'legacy_type_inference',
|
||||||
'sqlite_modules',
|
'sqlite_modules',
|
||||||
'eagerly_load_dart_ast'
|
'eagerly_load_dart_ast'
|
||||||
]);
|
]);
|
||||||
|
@ -44,9 +44,9 @@ MoorOptions _$MoorOptionsFromJson(Map<String, dynamic> json) {
|
||||||
generateConnectConstructor: $checkedConvert(
|
generateConnectConstructor: $checkedConvert(
|
||||||
json, 'generate_connect_constructor', (v) => v as bool) ??
|
json, 'generate_connect_constructor', (v) => v as bool) ??
|
||||||
false,
|
false,
|
||||||
useExperimentalInference: $checkedConvert(
|
legacyTypeInference:
|
||||||
json, 'use_experimental_inference', (v) => v as bool) ??
|
$checkedConvert(json, 'legacy_type_inference', (v) => v as bool) ??
|
||||||
false,
|
false,
|
||||||
eagerlyLoadDartAst:
|
eagerlyLoadDartAst:
|
||||||
$checkedConvert(json, 'eagerly_load_dart_ast', (v) => v as bool) ??
|
$checkedConvert(json, 'eagerly_load_dart_ast', (v) => v as bool) ??
|
||||||
false,
|
false,
|
||||||
|
|
|
@ -44,7 +44,7 @@ class MoorSession {
|
||||||
if (options.hasModule(SqlModule.json1)) const Json1Extension(),
|
if (options.hasModule(SqlModule.json1)) const Json1Extension(),
|
||||||
if (options.hasModule(SqlModule.moor_ffi)) const MoorFfiExtension(),
|
if (options.hasModule(SqlModule.moor_ffi)) const MoorFfiExtension(),
|
||||||
],
|
],
|
||||||
enableExperimentalTypeInference: options.useExperimentalInference,
|
useLegacyTypeInference: options.legacyTypeInference,
|
||||||
);
|
);
|
||||||
|
|
||||||
return SqlEngine(sqlOptions);
|
return SqlEngine(sqlOptions);
|
||||||
|
|
|
@ -89,10 +89,7 @@ import 'a.moor';
|
||||||
wrongArgs: SELECT sin(oid, foo) FROM numbers;
|
wrongArgs: SELECT sin(oid, foo) FROM numbers;
|
||||||
'''
|
'''
|
||||||
},
|
},
|
||||||
options: const MoorOptions(
|
options: const MoorOptions(modules: [SqlModule.moor_ffi]),
|
||||||
useExperimentalInference: true,
|
|
||||||
modules: [SqlModule.moor_ffi],
|
|
||||||
),
|
|
||||||
);
|
);
|
||||||
|
|
||||||
final fileA = await state.analyze('package:foo/a.moor');
|
final fileA = await state.analyze('package:foo/a.moor');
|
||||||
|
|
|
@ -3,7 +3,7 @@ import 'package:moor_generator/src/analyzer/options.dart';
|
||||||
import 'package:moor_generator/src/analyzer/runner/results.dart';
|
import 'package:moor_generator/src/analyzer/runner/results.dart';
|
||||||
import 'package:test/test.dart';
|
import 'package:test/test.dart';
|
||||||
|
|
||||||
import 'utils.dart';
|
import '../utils.dart';
|
||||||
|
|
||||||
void main() {
|
void main() {
|
||||||
test('experimental inference - integration test', () async {
|
test('experimental inference - integration test', () async {
|
||||||
|
@ -35,7 +35,7 @@ totalDurationByArtist:
|
||||||
INNER JOIN tracks ON tracks.album = albums.id
|
INNER JOIN tracks ON tracks.album = albums.id
|
||||||
GROUP BY artists.id;
|
GROUP BY artists.id;
|
||||||
'''
|
'''
|
||||||
}, options: const MoorOptions(useExperimentalInference: true));
|
}, options: const MoorOptions());
|
||||||
|
|
||||||
final file = await state.analyze('package:foo/a.moor');
|
final file = await state.analyze('package:foo/a.moor');
|
||||||
final result = file.currentResult as ParsedMoorFile;
|
final result = file.currentResult as ParsedMoorFile;
|
|
@ -5,6 +5,8 @@
|
||||||
tables with a comma will now be parsed as a `JoinClause`.
|
tables with a comma will now be parsed as a `JoinClause`.
|
||||||
- Changed `SelectStatementAsSource.statement` from `SelectStatement` to `BaseSelectStatement` and allow
|
- Changed `SelectStatementAsSource.statement` from `SelectStatement` to `BaseSelectStatement` and allow
|
||||||
compound select statements to appear in a `FROM` clause
|
compound select statements to appear in a `FROM` clause
|
||||||
|
- The new type inference engine is now enabled by default and the `enableExperimentalTypeInference` option
|
||||||
|
has been removed. To continue using the old engine, the `useLegacyTypeInference` flag can be used.
|
||||||
|
|
||||||
## 0.7.0
|
## 0.7.0
|
||||||
|
|
||||||
|
|
|
@ -29,6 +29,7 @@ class AnalysisContext {
|
||||||
/// A resolver that can be used to obtain the type of a [Typeable]. This
|
/// A resolver that can be used to obtain the type of a [Typeable]. This
|
||||||
/// mostly applies to [Expression]s, [Reference]s, [Variable]s and
|
/// mostly applies to [Expression]s, [Reference]s, [Variable]s and
|
||||||
/// [ResultSet.resolvedColumns] of a select statement.
|
/// [ResultSet.resolvedColumns] of a select statement.
|
||||||
|
@Deprecated('Used for legacy types only - consider migrating to types2')
|
||||||
/* late final */ TypeResolver types;
|
/* late final */ TypeResolver types;
|
||||||
|
|
||||||
/// Experimental new type resolver with better support for nullability and
|
/// Experimental new type resolver with better support for nullability and
|
||||||
|
@ -38,18 +39,13 @@ class AnalysisContext {
|
||||||
/// a [Variable] and [ResultSet.resolvedColumns] may be resolved or inferred.
|
/// a [Variable] and [ResultSet.resolvedColumns] may be resolved or inferred.
|
||||||
///
|
///
|
||||||
/// This field is null when experimental type inference is disabled.
|
/// This field is null when experimental type inference is disabled.
|
||||||
///
|
|
||||||
/// Please note that types2 is experimental at the moment. Changes to how
|
|
||||||
/// [types] resolves types are considered breaking and are handled
|
|
||||||
/// accordingly. [types2] may change results in any update.
|
|
||||||
@experimental
|
|
||||||
TypeInferenceResults types2;
|
TypeInferenceResults types2;
|
||||||
|
|
||||||
/// Constructs a new analysis context from the AST and the source sql.
|
/// Constructs a new analysis context from the AST and the source sql.
|
||||||
AnalysisContext(this.root, this.sql, this.engineOptions,
|
AnalysisContext(this.root, this.sql, this.engineOptions,
|
||||||
{AnalyzeStatementOptions stmtOptions, this.schemaSupport})
|
{AnalyzeStatementOptions stmtOptions, this.schemaSupport})
|
||||||
: stmtOptions = stmtOptions ?? const AnalyzeStatementOptions() {
|
: stmtOptions = stmtOptions ?? const AnalyzeStatementOptions() {
|
||||||
if (!engineOptions.enableExperimentalTypeInference) {
|
if (engineOptions.useLegacyTypeInference) {
|
||||||
types = TypeResolver(this, engineOptions);
|
types = TypeResolver(this, engineOptions);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,7 +9,7 @@ class TypeGraph {
|
||||||
final List<TypeRelation> _relations = [];
|
final List<TypeRelation> _relations = [];
|
||||||
|
|
||||||
final Map<Typeable, List<TypeRelation>> _edges = {};
|
final Map<Typeable, List<TypeRelation>> _edges = {};
|
||||||
final Set<MultiSourceRelation> _multiSources = {};
|
final Set<Typeable> _candidateForLaxMultiPropagation = {};
|
||||||
final List<DefaultType> _defaultTypes = [];
|
final List<DefaultType> _defaultTypes = [];
|
||||||
|
|
||||||
ResolvedType operator [](Typeable t) {
|
ResolvedType operator [](Typeable t) {
|
||||||
|
@ -51,14 +51,17 @@ class TypeGraph {
|
||||||
void performResolve() {
|
void performResolve() {
|
||||||
_indexRelations();
|
_indexRelations();
|
||||||
|
|
||||||
final queue = List.of(_knownTypes.keys);
|
var queue = List.of(_knownTypes.keys);
|
||||||
while (queue.isNotEmpty) {
|
while (queue.isNotEmpty) {
|
||||||
_propagateTypeInfo(queue, queue.removeLast());
|
_propagateTypeInfo(queue, queue.removeLast());
|
||||||
}
|
}
|
||||||
|
|
||||||
// propagate many-to-one sources where we don't know each source type
|
// propagate many-to-one sources where we don't know each source type, but
|
||||||
for (final remaining in _multiSources) {
|
// some of them.
|
||||||
_propagateManyToOne(remaining, queue);
|
queue = List.of(_candidateForLaxMultiPropagation);
|
||||||
|
while (queue.isNotEmpty) {
|
||||||
|
_propagateTypeInfo(queue, queue.removeLast(),
|
||||||
|
laxMultiSourcePropagation: true);
|
||||||
}
|
}
|
||||||
|
|
||||||
// apply default types
|
// apply default types
|
||||||
|
@ -77,7 +80,8 @@ class TypeGraph {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void _propagateTypeInfo(List<Typeable> resolved, Typeable t) {
|
void _propagateTypeInfo(List<Typeable> resolved, Typeable t,
|
||||||
|
{bool laxMultiSourcePropagation = false}) {
|
||||||
if (!_edges.containsKey(t)) return;
|
if (!_edges.containsKey(t)) return;
|
||||||
|
|
||||||
// propagate changes
|
// propagate changes
|
||||||
|
@ -93,10 +97,14 @@ class TypeGraph {
|
||||||
} else if (edge is CopyAndCast) {
|
} else if (edge is CopyAndCast) {
|
||||||
_copyType(resolved, t, edge.target, this[t].cast(edge.cast));
|
_copyType(resolved, t, edge.target, this[t].cast(edge.cast));
|
||||||
} else if (edge is MultiSourceRelation) {
|
} else if (edge is MultiSourceRelation) {
|
||||||
// handle many-to-one changes, if all targets have been resolved
|
// handle many-to-one changes, if all targets have been resolved or
|
||||||
if (edge.from.every(knowsType)) {
|
// lax handling is enabled.
|
||||||
_multiSources.remove(edge);
|
if (laxMultiSourcePropagation || edge.from.every(knowsType)) {
|
||||||
_propagateManyToOne(edge, resolved);
|
_propagateManyToOne(edge, resolved);
|
||||||
|
|
||||||
|
_candidateForLaxMultiPropagation.removeAll(edge.from);
|
||||||
|
} else {
|
||||||
|
_candidateForLaxMultiPropagation.add(t);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -165,7 +173,6 @@ class TypeGraph {
|
||||||
}
|
}
|
||||||
|
|
||||||
void putAll(MultiSourceRelation r) {
|
void putAll(MultiSourceRelation r) {
|
||||||
_multiSources.add(r);
|
|
||||||
for (final element in r.from) {
|
for (final element in r.from) {
|
||||||
put(element, r);
|
put(element, r);
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,6 +11,8 @@ const _expectString = ExactTypeExpectation.laxly(_textType);
|
||||||
class TypeResolver extends RecursiveVisitor<TypeExpectation, void> {
|
class TypeResolver extends RecursiveVisitor<TypeExpectation, void> {
|
||||||
final TypeInferenceSession session;
|
final TypeInferenceSession session;
|
||||||
|
|
||||||
|
final Set<Column> _handledColumns = {};
|
||||||
|
|
||||||
TypeResolver(this.session);
|
TypeResolver(this.session);
|
||||||
|
|
||||||
void run(AstNode root) {
|
void run(AstNode root) {
|
||||||
|
@ -414,6 +416,10 @@ class TypeResolver extends RecursiveVisitor<TypeExpectation, void> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
FunctionHandler /*?*/ _functionHandlerFor(ExpressionInvocation e) {
|
||||||
|
return session.options.addedFunctions[e.name.toLowerCase()];
|
||||||
|
}
|
||||||
|
|
||||||
ResolvedType _resolveInvocation(ExpressionInvocation e) {
|
ResolvedType _resolveInvocation(ExpressionInvocation e) {
|
||||||
final params = e.expandParameters();
|
final params = e.expandParameters();
|
||||||
void nullableIfChildIs() {
|
void nullableIfChildIs() {
|
||||||
|
@ -516,11 +522,9 @@ class TypeResolver extends RecursiveVisitor<TypeExpectation, void> {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
final addedFunctions = session.options.addedFunctions;
|
final extensionHandler = _functionHandlerFor(e);
|
||||||
if (addedFunctions.containsKey(lowercaseName)) {
|
if (extensionHandler != null) {
|
||||||
return addedFunctions[lowercaseName]
|
return extensionHandler.inferReturnType(session.context, e, params)?.type;
|
||||||
.inferReturnType(session.context, e, params)
|
|
||||||
?.type;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
session.context.reportError(AnalysisError(
|
session.context.reportError(AnalysisError(
|
||||||
|
@ -542,6 +546,25 @@ class TypeResolver extends RecursiveVisitor<TypeExpectation, void> {
|
||||||
visited.add(secondParam);
|
visited.add(secondParam);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
final extensionHandler =
|
||||||
|
e is ExpressionInvocation ? _functionHandlerFor(e) : null;
|
||||||
|
if (extensionHandler != null) {
|
||||||
|
for (final arg in params) {
|
||||||
|
if (arg is! Expression) continue;
|
||||||
|
|
||||||
|
final expressionArgument = arg as Expression;
|
||||||
|
|
||||||
|
final result = extensionHandler.inferArgumentType(
|
||||||
|
session.context, e, expressionArgument);
|
||||||
|
final type = result?.type;
|
||||||
|
if (type != null) {
|
||||||
|
session._markTypeResolved(expressionArgument, type);
|
||||||
|
}
|
||||||
|
|
||||||
|
visited.add(expressionArgument);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return visited;
|
return visited;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -558,12 +581,18 @@ class TypeResolver extends RecursiveVisitor<TypeExpectation, void> {
|
||||||
}
|
}
|
||||||
|
|
||||||
void _handleColumn(Column column) {
|
void _handleColumn(Column column) {
|
||||||
if (session.graph.knowsType(column)) return;
|
if (session.graph.knowsType(column) || _handledColumns.contains(column)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
_handledColumns.add(column);
|
||||||
|
|
||||||
if (column is TableColumn) {
|
if (column is TableColumn) {
|
||||||
session._markTypeResolved(column, column.type);
|
session._markTypeResolved(column, column.type);
|
||||||
} else if (column is ExpressionColumn) {
|
} else if (column is ExpressionColumn) {
|
||||||
_lazyCopy(column, column.expression);
|
_lazyCopy(column, column.expression);
|
||||||
|
} else if (column is CompoundSelectColumn) {
|
||||||
|
session._addRelation(CopyEncapsulating(column, column.columns));
|
||||||
|
column.columns.forEach(_handleColumn);
|
||||||
} else if (column is DelegatedColumn && column.innerColumn != null) {
|
} else if (column is DelegatedColumn && column.innerColumn != null) {
|
||||||
_handleColumn(column.innerColumn);
|
_handleColumn(column.innerColumn);
|
||||||
_lazyCopy(column, column.innerColumn);
|
_lazyCopy(column, column.innerColumn);
|
||||||
|
@ -605,5 +634,7 @@ class _ResultColumnVisitor extends RecursiveVisitor<void, void> {
|
||||||
if (stmt.resolvedColumns != null) {
|
if (stmt.resolvedColumns != null) {
|
||||||
stmt.resolvedColumns.forEach(resolver._handleColumn);
|
stmt.resolvedColumns.forEach(resolver._handleColumn);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
visitChildren(stmt, arg);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,8 +6,10 @@ class EngineOptions {
|
||||||
/// extensions enabled.
|
/// extensions enabled.
|
||||||
final bool useMoorExtensions;
|
final bool useMoorExtensions;
|
||||||
|
|
||||||
/// Enables the new, experimental type inference.
|
/// Whether the old type inference algorithm should be used.
|
||||||
final bool enableExperimentalTypeInference;
|
///
|
||||||
|
/// Defaults to false.
|
||||||
|
final bool useLegacyTypeInference;
|
||||||
|
|
||||||
/// All [Extension]s that have been enabled in this sql engine.
|
/// All [Extension]s that have been enabled in this sql engine.
|
||||||
final List<Extension> enabledExtensions;
|
final List<Extension> enabledExtensions;
|
||||||
|
@ -24,7 +26,7 @@ class EngineOptions {
|
||||||
EngineOptions({
|
EngineOptions({
|
||||||
this.useMoorExtensions = false,
|
this.useMoorExtensions = false,
|
||||||
this.enabledExtensions = const [],
|
this.enabledExtensions = const [],
|
||||||
this.enableExperimentalTypeInference = false,
|
this.useLegacyTypeInference = false,
|
||||||
});
|
});
|
||||||
|
|
||||||
void addFunctionHandler(FunctionHandler handler) {
|
void addFunctionHandler(FunctionHandler handler) {
|
||||||
|
|
|
@ -190,13 +190,13 @@ class SqlEngine {
|
||||||
..acceptWithoutArg(ColumnResolver(context))
|
..acceptWithoutArg(ColumnResolver(context))
|
||||||
..acceptWithoutArg(ReferenceResolver(context));
|
..acceptWithoutArg(ReferenceResolver(context));
|
||||||
|
|
||||||
if (options.enableExperimentalTypeInference) {
|
if (options.useLegacyTypeInference) {
|
||||||
|
node.acceptWithoutArg(TypeResolvingVisitor(context));
|
||||||
|
} else {
|
||||||
final session = t2.TypeInferenceSession(context, options);
|
final session = t2.TypeInferenceSession(context, options);
|
||||||
final resolver = t2.TypeResolver(session);
|
final resolver = t2.TypeResolver(session);
|
||||||
resolver.run(node);
|
resolver.run(node);
|
||||||
context.types2 = session.results;
|
context.types2 = session.results;
|
||||||
} else {
|
|
||||||
node.acceptWithoutArg(TypeResolvingVisitor(context));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
node.acceptWithoutArg(LintingVisitor(options, context));
|
node.acceptWithoutArg(LintingVisitor(options, context));
|
||||||
|
|
|
@ -42,7 +42,7 @@ Map<String, ResolveResult> _types = {
|
||||||
void main() {
|
void main() {
|
||||||
_types.forEach((sql, resolvedType) {
|
_types.forEach((sql, resolvedType) {
|
||||||
test('types: resolves in $sql', () {
|
test('types: resolves in $sql', () {
|
||||||
final engine = SqlEngine()
|
final engine = SqlEngine(EngineOptions(useLegacyTypeInference: true))
|
||||||
..registerTable(demoTable)
|
..registerTable(demoTable)
|
||||||
..registerTable(anotherTable);
|
..registerTable(anotherTable);
|
||||||
final content = engine.analyze(sql);
|
final content = engine.analyze(sql);
|
||||||
|
|
|
@ -39,9 +39,7 @@ const Map<String, ResolvedType> _types = {
|
||||||
};
|
};
|
||||||
|
|
||||||
SqlEngine _spawnEngine() {
|
SqlEngine _spawnEngine() {
|
||||||
return SqlEngine(EngineOptions(enableExperimentalTypeInference: true))
|
return SqlEngine()..registerTable(demoTable)..registerTable(anotherTable);
|
||||||
..registerTable(demoTable)
|
|
||||||
..registerTable(anotherTable);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void main() {
|
void main() {
|
||||||
|
|
|
@ -2,18 +2,18 @@ import 'package:sqlparser/sqlparser.dart';
|
||||||
import 'package:test/test.dart';
|
import 'package:test/test.dart';
|
||||||
|
|
||||||
void main() {
|
void main() {
|
||||||
group('json with stable inference', () {
|
group('json with legacy inference', () {
|
||||||
_runTests(false);
|
_runTests(false);
|
||||||
});
|
});
|
||||||
|
|
||||||
group('json with types2', () {
|
group('json with new type inference', () {
|
||||||
_runTests(true);
|
_runTests(true);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
void _runTests(bool types2) {
|
void _runTests(bool types2) {
|
||||||
final engine = SqlEngine(EngineOptions(
|
final engine = SqlEngine(EngineOptions(
|
||||||
enableExperimentalTypeInference: types2,
|
useLegacyTypeInference: !types2,
|
||||||
enabledExtensions: const [Json1Extension()],
|
enabledExtensions: const [Json1Extension()],
|
||||||
));
|
));
|
||||||
// add user (name, phone) table
|
// add user (name, phone) table
|
||||||
|
|
Loading…
Reference in New Issue