mirror of https://github.com/AMT-Cheif/drift.git
Add/Update TestCases for all introduced changes
This commit is contained in:
parent
f282ead955
commit
deaf58c5fb
|
@ -89,12 +89,25 @@ void main() {
|
|||
expect(result.errors, isEmpty);
|
||||
});
|
||||
|
||||
test('update statements with column-name-list', () {
|
||||
final result = engine.analyze(
|
||||
'WITH x AS (SELECT * FROM demo) UPDATE demo '
|
||||
'SET (id, content) = (x.id, x.content) FROM x WHERE demo.id = x.id;');
|
||||
expect(result.errors, isEmpty);
|
||||
});
|
||||
|
||||
test('insert statements', () {
|
||||
final result = engine.analyze(
|
||||
'WITH x AS (SELECT * FROM demo) INSERT INTO demo SELECT * FROM x;');
|
||||
expect(result.errors, isEmpty);
|
||||
});
|
||||
|
||||
test('insert statements with upsert using column-name-list', () {
|
||||
final result = engine.analyze(
|
||||
'WITH x AS (SELECT * FROM demo) INSERT INTO demo SELECT * FROM x ON CONFLICT(content) DO UPDATE SET (id, content) = (0, \'hello\');');
|
||||
expect(result.errors, isEmpty);
|
||||
});
|
||||
|
||||
test('delete statements', () {
|
||||
final result = engine.analyze(
|
||||
'WITH x AS (SELECT * FROM demo) DELETE FROM demo WHERE id IN (SELECT id FROM x);');
|
||||
|
|
|
@ -0,0 +1,72 @@
|
|||
import 'package:sqlparser/sqlparser.dart';
|
||||
import 'package:test/test.dart';
|
||||
|
||||
import '../data.dart';
|
||||
import 'utils.dart';
|
||||
|
||||
void main() {
|
||||
late SqlEngine engine;
|
||||
|
||||
setUp(() {
|
||||
engine = SqlEngine();
|
||||
engine.registerTableFromSql('''
|
||||
CREATE TABLE foo (
|
||||
a INTEGER NOT NULL,
|
||||
b INTEGER NOT NULL
|
||||
);
|
||||
''');
|
||||
});
|
||||
|
||||
group("using column-name-list and tuple in update", () {
|
||||
test('reports error if they have different sizes', () {
|
||||
engine
|
||||
.analyze("UPDATE foo SET (a, b) = (1);")
|
||||
.expectError('(1)', type: AnalysisErrorType.cteColumnCountMismatch);
|
||||
engine
|
||||
.analyze("UPDATE foo SET (a) = (1,2);")
|
||||
.expectError('(1,2)', type: AnalysisErrorType.cteColumnCountMismatch);
|
||||
});
|
||||
test('reports no error if they have same sizes', () {
|
||||
engine.analyze("UPDATE foo SET (a, b) = (1,2);").expectNoError();
|
||||
});
|
||||
});
|
||||
|
||||
group("using column-name-list and values in update", () {
|
||||
test('reports error if they have different sizes', () {
|
||||
engine.analyze("UPDATE foo SET (a, b) = (VALUES(1));").expectError(
|
||||
"(VALUES(1))",
|
||||
type: AnalysisErrorType.cteColumnCountMismatch);
|
||||
engine.analyze("UPDATE foo SET (a) = (VALUES(1,2));").expectError(
|
||||
"(VALUES(1,2))",
|
||||
type: AnalysisErrorType.cteColumnCountMismatch);
|
||||
});
|
||||
|
||||
test('reports no error if they have same sizes', () {
|
||||
engine.analyze("UPDATE foo SET (a, b) = (VALUES(1,2));").expectNoError();
|
||||
});
|
||||
});
|
||||
|
||||
group("using column-name-list and subquery in update", () {
|
||||
test('reports error if they have different sizes', () {
|
||||
engine.analyze("UPDATE foo SET (a, b) = (SELECT 1);").expectError(
|
||||
'(SELECT 1)',
|
||||
type: AnalysisErrorType.cteColumnCountMismatch);
|
||||
engine.analyze("UPDATE foo SET (a) = (SELECT 1,2);").expectError(
|
||||
'(SELECT 1,2)',
|
||||
type: AnalysisErrorType.cteColumnCountMismatch);
|
||||
engine
|
||||
.analyze(
|
||||
"UPDATE foo SET (a, b) = (SELECT b FROM foo as f WHERE f.a=a);")
|
||||
.expectError('(SELECT b FROM foo as f WHERE f.a=a)',
|
||||
type: AnalysisErrorType.cteColumnCountMismatch);
|
||||
});
|
||||
|
||||
test('reports no error if they have same sizes', () {
|
||||
engine.analyze("UPDATE foo SET (a, b) = (SELECT 1,2);").expectNoError();
|
||||
engine
|
||||
.analyze(
|
||||
"UPDATE foo SET (a, b) = (SELECT b, a FROM foo as f WHERE f.a=a);")
|
||||
.expectNoError();
|
||||
});
|
||||
});
|
||||
}
|
|
@ -23,6 +23,13 @@ void main() {
|
|||
.expectError('g', type: AnalysisErrorType.writeToGeneratedColumn);
|
||||
});
|
||||
|
||||
test('reports error when updating generated column with column-name-list',
|
||||
() {
|
||||
engine
|
||||
.analyze("UPDATE a SET (ok, g) = ('new', 'old');")
|
||||
.expectError('g', type: AnalysisErrorType.writeToGeneratedColumn);
|
||||
});
|
||||
|
||||
test('reports error when inserting generated column', () {
|
||||
engine
|
||||
.analyze('INSERT INTO a (ok, g) VALUES (?, ?)')
|
||||
|
|
|
@ -14,13 +14,18 @@ void main() {
|
|||
return TypeResolver(TypeInferenceSession(context))..run(context.root);
|
||||
}
|
||||
|
||||
ResolvedType? resolveFirstVariable(String sql,
|
||||
Iterable<ResolvedType?> resolveVariableTypes(String sql,
|
||||
{AnalyzeStatementOptions? options}) {
|
||||
final resolver = obtainResolver(sql, options: options);
|
||||
final session = resolver.session;
|
||||
final variable =
|
||||
session.context.root.allDescendants.whereType<Variable>().first;
|
||||
return session.typeOf(variable);
|
||||
return session.context.root.allDescendants
|
||||
.whereType<Variable>()
|
||||
.map((variable) => session.typeOf(variable));
|
||||
}
|
||||
|
||||
ResolvedType? resolveFirstVariable(String sql,
|
||||
{AnalyzeStatementOptions? options}) {
|
||||
return resolveVariableTypes(sql, options: options).first;
|
||||
}
|
||||
|
||||
ResolvedType? resolveResultColumn(String sql) {
|
||||
|
@ -292,6 +297,32 @@ WITH RECURSIVE
|
|||
expect(type, const ResolvedType(type: BasicType.int));
|
||||
});
|
||||
|
||||
test('handles multi column set components in updates', () {
|
||||
final variableTypes =
|
||||
resolveVariableTypes('UPDATE demo SET (id, content) = (?, ?)');
|
||||
expect(variableTypes.first, const ResolvedType(type: BasicType.int));
|
||||
expect(
|
||||
variableTypes.elementAt(1), const ResolvedType(type: BasicType.text));
|
||||
});
|
||||
|
||||
test('handles multi column set components in updates with select subquery',
|
||||
() {
|
||||
final variableTypes =
|
||||
resolveVariableTypes('UPDATE demo SET (id, content) = (SELECT ?,?)');
|
||||
expect(variableTypes.first, const ResolvedType(type: BasicType.int));
|
||||
expect(
|
||||
variableTypes.elementAt(1), const ResolvedType(type: BasicType.text));
|
||||
});
|
||||
|
||||
test('handles multi column set components in updates with values subquery',
|
||||
() {
|
||||
final variableTypes =
|
||||
resolveVariableTypes('UPDATE demo SET (id, content) = (VALUES(?,?))');
|
||||
expect(variableTypes.first, const ResolvedType(type: BasicType.int));
|
||||
expect(
|
||||
variableTypes.elementAt(1), const ResolvedType(type: BasicType.text));
|
||||
});
|
||||
|
||||
test('infers offsets in frame specs', () {
|
||||
final type = resolveFirstVariable('SELECT SUM(id) OVER (ROWS ? PRECEDING)');
|
||||
expect(type, const ResolvedType(type: BasicType.int));
|
||||
|
|
|
@ -26,6 +26,51 @@ void main() {
|
|||
testAll(testCases);
|
||||
});
|
||||
|
||||
test('parses updates with column-name-list and subquery', () {
|
||||
testStatement(
|
||||
'''
|
||||
UPDATE foo
|
||||
SET (a, b) = (SELECT b, a FROM bar AS b WHERE b.id=foo.id);
|
||||
''',
|
||||
UpdateStatement(table: TableReference('foo'), set: [
|
||||
MultiColumnSetComponent(
|
||||
columns: [Reference(columnName: 'a'), Reference(columnName: 'b')],
|
||||
rowValue: SubQuery(
|
||||
select: SelectStatement(
|
||||
columns: [
|
||||
ExpressionResultColumn(
|
||||
expression: Reference(columnName: 'b'),
|
||||
),
|
||||
ExpressionResultColumn(
|
||||
expression: Reference(columnName: 'a'),
|
||||
),
|
||||
],
|
||||
from: TableReference('bar', as: 'b'),
|
||||
where: BinaryExpression(
|
||||
Reference(entityName: 'b', columnName: 'id'),
|
||||
token(TokenType.equal),
|
||||
Reference(entityName: 'foo', columnName: 'id'),
|
||||
))))
|
||||
]));
|
||||
});
|
||||
|
||||
test('parses updates with column-name-list and scalar rowValues', () {
|
||||
testStatement(
|
||||
'''
|
||||
UPDATE foo
|
||||
SET (a, b) = (b, 3+4);
|
||||
''',
|
||||
UpdateStatement(table: TableReference('foo'), set: [
|
||||
MultiColumnSetComponent(
|
||||
columns: [Reference(columnName: 'a'), Reference(columnName: 'b')],
|
||||
rowValue: Tuple(expressions: [
|
||||
Reference(columnName: "b"),
|
||||
BinaryExpression(NumericLiteral(3), token(TokenType.plus),
|
||||
NumericLiteral(4)),
|
||||
], usedAsRowValue: true))
|
||||
]));
|
||||
});
|
||||
|
||||
test('parses updates with FROM clause', () {
|
||||
testStatement(
|
||||
'''
|
||||
|
|
Loading…
Reference in New Issue