mirror of https://github.com/AMT-Cheif/drift.git
Lint for distinct aggregate with more than one arg
This commit is contained in:
parent
78470b4280
commit
98163103d5
|
@ -1,3 +1,7 @@
|
||||||
|
## 0.21.1-dev
|
||||||
|
|
||||||
|
- Lint for `DISTINCT` misuse in aggregate function calls.
|
||||||
|
|
||||||
## 0.21.0
|
## 0.21.0
|
||||||
|
|
||||||
- Analysis support for new features in sqlite version 3.38.
|
- Analysis support for new features in sqlite version 3.38.
|
||||||
|
|
|
@ -80,6 +80,7 @@ enum AnalysisErrorType {
|
||||||
missingPrimaryKey,
|
missingPrimaryKey,
|
||||||
noTypeNameInStrictTable,
|
noTypeNameInStrictTable,
|
||||||
invalidTypeNameInStrictTable,
|
invalidTypeNameInStrictTable,
|
||||||
|
distinctAggregateWithWrongParameterCount,
|
||||||
other,
|
other,
|
||||||
hint,
|
hint,
|
||||||
}
|
}
|
||||||
|
|
|
@ -204,6 +204,19 @@ class LintingVisitor extends RecursiveVisitor<void, void> {
|
||||||
visitChildren(e, arg);
|
visitChildren(e, arg);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
void visitExpressionFunctionParameters(ExprFunctionParameters e, void arg) {
|
||||||
|
if (e.distinct && e.parameters.length != 1) {
|
||||||
|
context.reportError(AnalysisError(
|
||||||
|
type: AnalysisErrorType.distinctAggregateWithWrongParameterCount,
|
||||||
|
message: 'A `DISTINCT` aggregate must have exactly one argument',
|
||||||
|
relevantNode: e.distinctKeyword ?? e,
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
visitChildren(e, arg);
|
||||||
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void visitInvocation(SqlInvocation e, void arg) {
|
void visitInvocation(SqlInvocation e, void arg) {
|
||||||
final lowercaseCall = e.name.toLowerCase();
|
final lowercaseCall = e.name.toLowerCase();
|
||||||
|
|
|
@ -66,6 +66,7 @@ class StarFunctionParameter extends FunctionParameters {
|
||||||
|
|
||||||
class ExprFunctionParameters extends FunctionParameters {
|
class ExprFunctionParameters extends FunctionParameters {
|
||||||
final bool distinct;
|
final bool distinct;
|
||||||
|
Token? distinctKeyword;
|
||||||
List<Expression> parameters;
|
List<Expression> parameters;
|
||||||
|
|
||||||
ExprFunctionParameters({this.parameters = const [], this.distinct = false});
|
ExprFunctionParameters({this.parameters = const [], this.distinct = false});
|
||||||
|
|
|
@ -89,6 +89,13 @@ class Parser {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Token? _matchOneAndGet(TokenType type) {
|
||||||
|
if (_matchOne(type)) {
|
||||||
|
return _previous;
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
/// Returns true if the next token is [type] or if the next two tokens are
|
/// Returns true if the next token is [type] or if the next two tokens are
|
||||||
/// "NOT" followed by [type]. Does not consume any tokens.
|
/// "NOT" followed by [type]. Does not consume any tokens.
|
||||||
bool _checkWithNot(TokenType type) {
|
bool _checkWithNot(TokenType type) {
|
||||||
|
@ -901,7 +908,7 @@ class Parser {
|
||||||
return ExprFunctionParameters(parameters: const [])..synthetic = true;
|
return ExprFunctionParameters(parameters: const [])..synthetic = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
final distinct = _matchOne(TokenType.distinct);
|
final distinct = _matchOneAndGet(TokenType.distinct);
|
||||||
final parameters = <Expression>[];
|
final parameters = <Expression>[];
|
||||||
final first = _peek;
|
final first = _peek;
|
||||||
|
|
||||||
|
@ -909,7 +916,9 @@ class Parser {
|
||||||
parameters.add(expression());
|
parameters.add(expression());
|
||||||
} while (_matchOne(TokenType.comma));
|
} while (_matchOne(TokenType.comma));
|
||||||
|
|
||||||
return ExprFunctionParameters(distinct: distinct, parameters: parameters)
|
return ExprFunctionParameters(
|
||||||
|
distinct: distinct != null, parameters: parameters)
|
||||||
|
..distinctKeyword = distinct
|
||||||
..setSpan(first, _previous);
|
..setSpan(first, _previous);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,16 @@
|
||||||
|
import 'package:sqlparser/sqlparser.dart';
|
||||||
|
import 'package:test/test.dart';
|
||||||
|
|
||||||
|
import '../data.dart';
|
||||||
|
import 'utils.dart';
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
final engine = SqlEngine()..registerTable(demoTable);
|
||||||
|
|
||||||
|
test('warns about multiple parameters with DISTINCT', () {
|
||||||
|
engine
|
||||||
|
.analyze("SELECT group_concat(DISTINCT content, '-') FROM demo")
|
||||||
|
.expectError('DISTINCT',
|
||||||
|
type: AnalysisErrorType.distinctAggregateWithWrongParameterCount);
|
||||||
|
});
|
||||||
|
}
|
Loading…
Reference in New Issue