mirror of https://github.com/AMT-Cheif/drift.git
209 lines
6.4 KiB
Dart
209 lines
6.4 KiB
Dart
import 'package:sqlparser/src/ast/ast.dart';
|
|
import 'package:sqlparser/src/reader/parser/parser.dart';
|
|
import 'package:sqlparser/src/reader/tokenizer/scanner.dart';
|
|
import 'package:sqlparser/src/reader/tokenizer/token.dart';
|
|
import 'package:sqlparser/src/utils/ast_equality.dart';
|
|
import 'package:test/test.dart';
|
|
|
|
import 'utils.dart';
|
|
|
|
final Map<String, Expression> _testCases = {
|
|
'3 * 7 + 1 NOT BETWEEN 31 AND 74': BetweenExpression(
|
|
not: true,
|
|
check: BinaryExpression(
|
|
BinaryExpression(
|
|
NumericLiteral(3, token(TokenType.numberLiteral)),
|
|
token(TokenType.star),
|
|
NumericLiteral(7, token(TokenType.numberLiteral)),
|
|
),
|
|
token(TokenType.plus),
|
|
NumericLiteral(1, token(TokenType.numberLiteral)),
|
|
),
|
|
lower: NumericLiteral(31, token(TokenType.numberLiteral)),
|
|
upper: NumericLiteral(74, token(TokenType.numberLiteral)),
|
|
),
|
|
'3 * 4 + 5 == COUNT(*)': BinaryExpression(
|
|
BinaryExpression(
|
|
BinaryExpression(
|
|
NumericLiteral(3, token(TokenType.numberLiteral)),
|
|
token(TokenType.star),
|
|
NumericLiteral(4, token(TokenType.numberLiteral)),
|
|
),
|
|
token(TokenType.plus),
|
|
NumericLiteral(5, token(TokenType.numberLiteral)),
|
|
),
|
|
token(TokenType.doubleEqual),
|
|
FunctionExpression(
|
|
name: 'COUNT',
|
|
parameters: StarFunctionParameter(),
|
|
),
|
|
),
|
|
'? * ?3 + ?2 == :test': BinaryExpression(
|
|
BinaryExpression(
|
|
BinaryExpression(
|
|
NumberedVariable(QuestionMarkVariableToken(fakeSpan('?'), null)),
|
|
token(TokenType.star),
|
|
NumberedVariable(QuestionMarkVariableToken(fakeSpan('?3'), 3)),
|
|
),
|
|
token(TokenType.plus),
|
|
NumberedVariable(QuestionMarkVariableToken(fakeSpan('?2'), 2)),
|
|
),
|
|
token(TokenType.doubleEqual),
|
|
ColonNamedVariable(ColonVariableToken(fakeSpan(':test'), ':test')),
|
|
),
|
|
'CASE x WHEN a THEN b WHEN c THEN d ELSE e END': CaseExpression(
|
|
base: Reference(columnName: 'x'),
|
|
whens: [
|
|
WhenComponent(
|
|
when: Reference(columnName: 'a'),
|
|
then: Reference(columnName: 'b'),
|
|
),
|
|
WhenComponent(
|
|
when: Reference(columnName: 'c'),
|
|
then: Reference(columnName: 'd'),
|
|
),
|
|
],
|
|
elseExpr: Reference(columnName: 'e'),
|
|
),
|
|
'CASE WHEN a THEN '
|
|
'CASE WHEN b THEN c ELSE d END '
|
|
'ELSE '
|
|
'CASE WHEN e THEN f ELSE g END '
|
|
'END': CaseExpression(
|
|
whens: [
|
|
WhenComponent(
|
|
when: Reference(columnName: 'a'),
|
|
then: CaseExpression(
|
|
whens: [
|
|
WhenComponent(
|
|
when: Reference(columnName: 'b'),
|
|
then: Reference(columnName: 'c'),
|
|
),
|
|
],
|
|
elseExpr: Reference(columnName: 'd'),
|
|
),
|
|
),
|
|
],
|
|
elseExpr: CaseExpression(
|
|
whens: [
|
|
WhenComponent(
|
|
when: Reference(columnName: 'e'),
|
|
then: Reference(columnName: 'f'),
|
|
),
|
|
],
|
|
elseExpr: Reference(columnName: 'g'),
|
|
),
|
|
),
|
|
"x NOT LIKE '%A%\$' ESCAPE '\$'": StringComparisonExpression(
|
|
not: true,
|
|
left: Reference(columnName: 'x'),
|
|
operator: token(TokenType.like),
|
|
right: StringLiteral.from(token(TokenType.stringLiteral), '%A%\$'),
|
|
escape: StringLiteral.from(token(TokenType.stringLiteral), '\$'),
|
|
),
|
|
'NOT EXISTS (SELECT * FROM demo)': UnaryExpression(
|
|
token(TokenType.not),
|
|
ExistsExpression(
|
|
select: SelectStatement(
|
|
columns: [StarResultColumn(null)],
|
|
from: TableReference('demo', null),
|
|
),
|
|
),
|
|
),
|
|
'(SELECT x)': SubQuery(
|
|
select: SelectStatement(
|
|
columns: [
|
|
ExpressionResultColumn(
|
|
expression: Reference(columnName: 'x'),
|
|
),
|
|
],
|
|
),
|
|
),
|
|
"'hello' || 'world' COLLATE NOCASE": BinaryExpression(
|
|
StringLiteral.from(token(TokenType.stringLiteral), 'hello'),
|
|
token(TokenType.doublePipe),
|
|
CollateExpression(
|
|
operator: token(TokenType.collate),
|
|
inner: StringLiteral.from(token(TokenType.stringLiteral), 'world'),
|
|
collateFunction: token(TokenType.identifier),
|
|
),
|
|
),
|
|
'x in ?': InExpression(
|
|
left: Reference(columnName: 'x'),
|
|
inside: NumberedVariable(QuestionMarkVariableToken(fakeSpan('?'), null)),
|
|
),
|
|
'x IN (SELECT col FROM tbl)': InExpression(
|
|
left: Reference(columnName: 'x'),
|
|
inside: SubQuery(
|
|
select: SelectStatement(
|
|
columns: [
|
|
ExpressionResultColumn(
|
|
expression: Reference(columnName: 'col'),
|
|
)
|
|
],
|
|
from: TableReference('tbl', null),
|
|
),
|
|
),
|
|
),
|
|
'x IN (1, 2, (SELECT 3))': InExpression(
|
|
left: Reference(columnName: 'x'),
|
|
inside: Tuple(
|
|
expressions: [
|
|
NumericLiteral(1.0, token(TokenType.numberLiteral)),
|
|
NumericLiteral(2.0, token(TokenType.numberLiteral)),
|
|
SubQuery(
|
|
select: SelectStatement(columns: [
|
|
ExpressionResultColumn(
|
|
expression: NumericLiteral(3.0, token(TokenType.numberLiteral)),
|
|
),
|
|
]),
|
|
),
|
|
],
|
|
),
|
|
),
|
|
'CAST(3 + 4 AS TEXT)': CastExpression(
|
|
BinaryExpression(
|
|
NumericLiteral(3.0, token(TokenType.numberLiteral)),
|
|
token(TokenType.plus),
|
|
NumericLiteral(4.0, token(TokenType.numberLiteral)),
|
|
),
|
|
'TEXT',
|
|
),
|
|
'foo ISNULL': IsNullExpression(Reference(columnName: 'foo')),
|
|
'foo NOTNULL': IsNullExpression(Reference(columnName: 'foo'), true),
|
|
'CURRENT_TIME': TimeConstantLiteral(
|
|
TimeConstantKind.currentTime, token(TokenType.currentTime)),
|
|
'CURRENT_TIMESTAMP': TimeConstantLiteral(
|
|
TimeConstantKind.currentTimestamp, token(TokenType.currentTimestamp)),
|
|
'CURRENT_DATE': TimeConstantLiteral(
|
|
TimeConstantKind.currentDate, token(TokenType.currentDate)),
|
|
'(1, 2, 3) > (?, ?, ?)': BinaryExpression(
|
|
Tuple(expressions: [
|
|
for (var i = 1; i <= 3; i++)
|
|
NumericLiteral(i, token(TokenType.numberLiteral)),
|
|
]),
|
|
token(TokenType.more),
|
|
Tuple(expressions: [
|
|
NumberedVariable(QuestionMarkVariableToken(fakeSpan('?'), null)),
|
|
NumberedVariable(QuestionMarkVariableToken(fakeSpan('?'), null)),
|
|
NumberedVariable(QuestionMarkVariableToken(fakeSpan('?'), null)),
|
|
]),
|
|
),
|
|
};
|
|
|
|
void main() {
|
|
group('expresssion test cases', () {
|
|
_testCases.forEach((sql, expected) {
|
|
test(sql, () {
|
|
final scanner = Scanner(sql);
|
|
final tokens = scanner.scanTokens();
|
|
final parser = Parser(tokens);
|
|
final expression = parser.expression();
|
|
|
|
enforceHasSpan(expression);
|
|
enforceEqual(expression, expected);
|
|
});
|
|
});
|
|
});
|
|
}
|