mirror of https://github.com/AMT-Cheif/drift.git
Prepare parser for schema support
This commit is contained in:
parent
f23cf9f426
commit
aa75cbaa19
|
@ -42,13 +42,14 @@ abstract class TableOrSubquery extends Queryable {
|
||||||
class TableReference extends TableOrSubquery
|
class TableReference extends TableOrSubquery
|
||||||
with ReferenceOwner
|
with ReferenceOwner
|
||||||
implements Renamable, ResolvesToResultSet {
|
implements Renamable, ResolvesToResultSet {
|
||||||
|
final String? schemaName;
|
||||||
final String tableName;
|
final String tableName;
|
||||||
Token? tableNameToken;
|
Token? tableNameToken;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
final String? as;
|
final String? as;
|
||||||
|
|
||||||
TableReference(this.tableName, [this.as]);
|
TableReference(this.tableName, {this.as, this.schemaName});
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Iterable<AstNode> get childNodes => const [];
|
Iterable<AstNode> get childNodes => const [];
|
||||||
|
|
|
@ -8,6 +8,11 @@ part of '../ast.dart';
|
||||||
/// 2 * c AS d FROM table", the "c" after the "2 *" is a reference that refers
|
/// 2 * c AS d FROM table", the "c" after the "2 *" is a reference that refers
|
||||||
/// to the expression "COUNT(*)".
|
/// to the expression "COUNT(*)".
|
||||||
class Reference extends Expression with ReferenceOwner {
|
class Reference extends Expression with ReferenceOwner {
|
||||||
|
/// An optional schema name.
|
||||||
|
///
|
||||||
|
/// When this is non-null, [entityName] will not be null either.
|
||||||
|
final String? schemaName;
|
||||||
|
|
||||||
/// Entity can be either a table or a view.
|
/// Entity can be either a table or a view.
|
||||||
final String? entityName;
|
final String? entityName;
|
||||||
final String columnName;
|
final String columnName;
|
||||||
|
@ -17,7 +22,11 @@ class Reference extends Expression with ReferenceOwner {
|
||||||
|
|
||||||
Column? get resolvedColumn => resolved as Column?;
|
Column? get resolvedColumn => resolved as Column?;
|
||||||
|
|
||||||
Reference({this.entityName, required this.columnName});
|
Reference({this.entityName, this.schemaName, required this.columnName})
|
||||||
|
: assert(
|
||||||
|
entityName != null || schemaName == null,
|
||||||
|
'When setting a schemaName, entityName must not be null either.',
|
||||||
|
);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
R accept<A, R>(AstVisitor<A, R> visitor, A arg) {
|
R accept<A, R>(AstVisitor<A, R> visitor, A arg) {
|
||||||
|
@ -32,10 +41,16 @@ class Reference extends Expression with ReferenceOwner {
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String toString() {
|
String toString() {
|
||||||
if (entityName != null) {
|
final result = StringBuffer();
|
||||||
return 'Reference to the column $entityName.$columnName';
|
|
||||||
} else {
|
if (schemaName != null) {
|
||||||
return 'Reference to the column $columnName';
|
result..write(schemaName)..write('.');
|
||||||
}
|
}
|
||||||
|
if (entityName != null) {
|
||||||
|
result..write(entityName)..write('.');
|
||||||
|
}
|
||||||
|
result.write(columnName);
|
||||||
|
|
||||||
|
return result.toString();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -751,32 +751,7 @@ class Parser {
|
||||||
|
|
||||||
return CastExpression(operand, typeName)..setSpan(first, _previous);
|
return CastExpression(operand, typeName)..setSpan(first, _previous);
|
||||||
} else if (_checkIdentifier()) {
|
} else if (_checkIdentifier()) {
|
||||||
final first = _consumeIdentifier(
|
return _referenceOrFunctionCall();
|
||||||
'This error message should never be displayed. Please report.');
|
|
||||||
|
|
||||||
// could be table.column, function(...) or just column
|
|
||||||
if (_matchOne(TokenType.dot)) {
|
|
||||||
final second =
|
|
||||||
_consumeIdentifier('Expected a column name here', lenient: true);
|
|
||||||
return Reference(
|
|
||||||
entityName: first.identifier, columnName: second.identifier)
|
|
||||||
..setSpan(first, second);
|
|
||||||
} else if (_matchOne(TokenType.leftParen)) {
|
|
||||||
// regular function invocation
|
|
||||||
final parameters = _functionParameters();
|
|
||||||
final rightParen = _consume(TokenType.rightParen,
|
|
||||||
'Expected closing bracket after argument list');
|
|
||||||
|
|
||||||
if (_peek.type == TokenType.filter || _peek.type == TokenType.over) {
|
|
||||||
return _aggregate(first, parameters);
|
|
||||||
}
|
|
||||||
|
|
||||||
return FunctionExpression(
|
|
||||||
name: first.identifier, parameters: parameters)
|
|
||||||
..setSpan(first, rightParen);
|
|
||||||
} else {
|
|
||||||
return Reference(columnName: first.identifier)..setSpan(first, first);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_peek is KeywordToken) {
|
if (_peek is KeywordToken) {
|
||||||
|
@ -787,6 +762,55 @@ class Parser {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Expression _referenceOrFunctionCall() {
|
||||||
|
final first = _consumeIdentifier(
|
||||||
|
'This error message should never be displayed. Please report.');
|
||||||
|
|
||||||
|
// An expression starting with an identifier could be three things:
|
||||||
|
// - a simple reference: "foo"
|
||||||
|
// - a reference with a table: "foo.bar"
|
||||||
|
// - a reference with a table and a schema: "foo.bar.baz"
|
||||||
|
// - a function call: "foo()"
|
||||||
|
|
||||||
|
if (_matchOne(TokenType.dot)) {
|
||||||
|
// Ok, we're down to two here. it's either a table or a schema ref
|
||||||
|
final second = _consumeIdentifier('Expected a column or table name here',
|
||||||
|
lenient: true);
|
||||||
|
|
||||||
|
if (_matchOne(TokenType.dot)) {
|
||||||
|
// Three identifiers, that's a schema reference
|
||||||
|
final third =
|
||||||
|
_consumeIdentifier('Expected a column name here', lenient: true);
|
||||||
|
return Reference(
|
||||||
|
schemaName: first.identifier,
|
||||||
|
entityName: second.identifier,
|
||||||
|
columnName: third.identifier,
|
||||||
|
)..setSpan(first, third);
|
||||||
|
} else {
|
||||||
|
// Two identifiers only, so we have a table-based reference
|
||||||
|
return Reference(
|
||||||
|
entityName: first.identifier,
|
||||||
|
columnName: second.identifier,
|
||||||
|
)..setSpan(first, second);
|
||||||
|
}
|
||||||
|
} else if (_matchOne(TokenType.leftParen)) {
|
||||||
|
// We have something like "foo(" -> that's a function!
|
||||||
|
final parameters = _functionParameters();
|
||||||
|
final rightParen = _consume(
|
||||||
|
TokenType.rightParen, 'Expected closing bracket after argument list');
|
||||||
|
|
||||||
|
if (_peek.type == TokenType.filter || _peek.type == TokenType.over) {
|
||||||
|
return _aggregate(first, parameters);
|
||||||
|
}
|
||||||
|
|
||||||
|
return FunctionExpression(name: first.identifier, parameters: parameters)
|
||||||
|
..setSpan(first, rightParen);
|
||||||
|
} else {
|
||||||
|
// Ok, just a regular reference then
|
||||||
|
return Reference(columnName: first.identifier)..setSpan(first, first);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Variable? _variableOrNull() {
|
Variable? _variableOrNull() {
|
||||||
if (_matchOne(TokenType.questionMarkVariable)) {
|
if (_matchOne(TokenType.questionMarkVariable)) {
|
||||||
return NumberedVariable(_previous as QuestionMarkVariableToken)
|
return NumberedVariable(_previous as QuestionMarkVariableToken)
|
||||||
|
@ -1171,19 +1195,6 @@ class Parser {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
TableReference _tableReference() {
|
|
||||||
_suggestHint(const TableNameDescription());
|
|
||||||
// ignore the schema name, it's not supported. Besides that, we're on the
|
|
||||||
// first branch in the diagram here https://www.sqlite.org/syntax/table-or-subquery.html
|
|
||||||
final firstToken = _consumeIdentifier('Expected a table reference');
|
|
||||||
|
|
||||||
final tableName = firstToken.identifier;
|
|
||||||
final alias = _as();
|
|
||||||
return TableReference(tableName, alias?.identifier)
|
|
||||||
..setSpan(firstToken, _previous)
|
|
||||||
..tableNameToken = firstToken;
|
|
||||||
}
|
|
||||||
|
|
||||||
JoinClause? _joinClause(TableOrSubquery start) {
|
JoinClause? _joinClause(TableOrSubquery start) {
|
||||||
var operator = _parseJoinOperator();
|
var operator = _parseJoinOperator();
|
||||||
if (operator == null) {
|
if (operator == null) {
|
||||||
|
@ -2424,15 +2435,37 @@ class Parser {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TableReference _tableReference({bool allowAlias = true}) {
|
||||||
|
_suggestHint(const TableNameDescription());
|
||||||
|
|
||||||
|
final first = _consumeIdentifier('Expected table or schema name here');
|
||||||
|
IdentifierToken? second;
|
||||||
|
IdentifierToken? as;
|
||||||
|
if (_matchOne(TokenType.dot)) {
|
||||||
|
second = _consumeIdentifier('Expected a table name here');
|
||||||
|
}
|
||||||
|
|
||||||
|
if (allowAlias) {
|
||||||
|
as = _as();
|
||||||
|
}
|
||||||
|
|
||||||
|
final tableNameToken = second ?? first;
|
||||||
|
|
||||||
|
return TableReference(
|
||||||
|
tableNameToken.identifier,
|
||||||
|
as: as?.identifier,
|
||||||
|
schemaName: second == null ? null : first.identifier,
|
||||||
|
)
|
||||||
|
..setSpan(first, _previous)
|
||||||
|
..tableNameToken = tableNameToken;
|
||||||
|
}
|
||||||
|
|
||||||
ForeignKeyClause _foreignKeyClause() {
|
ForeignKeyClause _foreignKeyClause() {
|
||||||
// https://www.sqlite.org/syntax/foreign-key-clause.html
|
// https://www.sqlite.org/syntax/foreign-key-clause.html
|
||||||
_consume(TokenType.references, 'Expected REFERENCES');
|
_consume(TokenType.references, 'Expected REFERENCES');
|
||||||
final firstToken = _previous;
|
final firstToken = _previous;
|
||||||
|
|
||||||
final foreignTable = _consumeIdentifier('Expected a table name');
|
final foreignTable = _tableReference(allowAlias: false);
|
||||||
final foreignTableName = TableReference(foreignTable.identifier, null)
|
|
||||||
..setSpan(foreignTable, foreignTable);
|
|
||||||
|
|
||||||
final columnNames = _listColumnsInParentheses(allowEmpty: true);
|
final columnNames = _listColumnsInParentheses(allowEmpty: true);
|
||||||
|
|
||||||
ReferenceAction? onDelete, onUpdate;
|
ReferenceAction? onDelete, onUpdate;
|
||||||
|
@ -2472,7 +2505,7 @@ class Parser {
|
||||||
}
|
}
|
||||||
|
|
||||||
return ForeignKeyClause(
|
return ForeignKeyClause(
|
||||||
foreignTable: foreignTableName,
|
foreignTable: foreignTable,
|
||||||
columnNames: columnNames,
|
columnNames: columnNames,
|
||||||
onUpdate: onUpdate,
|
onUpdate: onUpdate,
|
||||||
onDelete: onDelete,
|
onDelete: onDelete,
|
||||||
|
|
|
@ -547,7 +547,8 @@ class EqualityEnforcingVisitor implements AstVisitor<void, void> {
|
||||||
void visitReference(Reference e, void arg) {
|
void visitReference(Reference e, void arg) {
|
||||||
final current = _currentAs<Reference>(e);
|
final current = _currentAs<Reference>(e);
|
||||||
_assert(
|
_assert(
|
||||||
current.entityName == e.entityName &&
|
current.schemaName == e.schemaName &&
|
||||||
|
current.entityName == e.entityName &&
|
||||||
current.columnName == e.columnName,
|
current.columnName == e.columnName,
|
||||||
e);
|
e);
|
||||||
_checkChildren(e);
|
_checkChildren(e);
|
||||||
|
@ -628,7 +629,11 @@ class EqualityEnforcingVisitor implements AstVisitor<void, void> {
|
||||||
@override
|
@override
|
||||||
void visitTableReference(TableReference e, void arg) {
|
void visitTableReference(TableReference e, void arg) {
|
||||||
final current = _currentAs<TableReference>(e);
|
final current = _currentAs<TableReference>(e);
|
||||||
_assert(current.tableName == e.tableName && current.as == e.as, e);
|
_assert(
|
||||||
|
current.schemaName == e.schemaName &&
|
||||||
|
current.tableName == e.tableName &&
|
||||||
|
current.as == e.as,
|
||||||
|
e);
|
||||||
_checkChildren(e);
|
_checkChildren(e);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -964,14 +964,22 @@ class NodeSqlBuilder extends AstVisitor<void, void> {
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void visitReference(Reference e, void arg) {
|
void visitReference(Reference e, void arg) {
|
||||||
var hasTable = false;
|
var didWriteSpaceBefore = false;
|
||||||
if (e.entityName != null) {
|
|
||||||
hasTable = true;
|
if (e.schemaName != null) {
|
||||||
_identifier(e.entityName!, spaceAfter: false);
|
_identifier(e.schemaName!, spaceAfter: false);
|
||||||
_symbol('.');
|
_symbol('.');
|
||||||
|
didWriteSpaceBefore = true;
|
||||||
|
}
|
||||||
|
if (e.entityName != null) {
|
||||||
|
_identifier(e.entityName!,
|
||||||
|
spaceAfter: false, spaceBefore: !didWriteSpaceBefore);
|
||||||
|
_symbol('.');
|
||||||
|
didWriteSpaceBefore = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
_identifier(e.columnName, spaceAfter: true, spaceBefore: !hasTable);
|
_identifier(e.columnName,
|
||||||
|
spaceAfter: true, spaceBefore: !didWriteSpaceBefore);
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
|
@ -1131,7 +1139,12 @@ class NodeSqlBuilder extends AstVisitor<void, void> {
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void visitTableReference(TableReference e, void arg) {
|
void visitTableReference(TableReference e, void arg) {
|
||||||
_identifier(e.tableName);
|
if (e.schemaName != null) {
|
||||||
|
_identifier(e.schemaName!, spaceAfter: false);
|
||||||
|
_symbol('.');
|
||||||
|
}
|
||||||
|
_identifier(e.tableName, spaceBefore: e.schemaName == null);
|
||||||
|
|
||||||
if (e.as != null) {
|
if (e.as != null) {
|
||||||
_keyword(TokenType.as);
|
_keyword(TokenType.as);
|
||||||
_identifier(e.as!);
|
_identifier(e.as!);
|
||||||
|
|
|
@ -77,7 +77,7 @@ void main() {
|
||||||
ForeignKeyColumnConstraint(
|
ForeignKeyColumnConstraint(
|
||||||
null,
|
null,
|
||||||
ForeignKeyClause(
|
ForeignKeyClause(
|
||||||
foreignTable: TableReference('some', null),
|
foreignTable: TableReference('some'),
|
||||||
columnNames: [Reference(columnName: 'thing')],
|
columnNames: [Reference(columnName: 'thing')],
|
||||||
onUpdate: ReferenceAction.cascade,
|
onUpdate: ReferenceAction.cascade,
|
||||||
onDelete: ReferenceAction.setNull,
|
onDelete: ReferenceAction.setNull,
|
||||||
|
@ -107,7 +107,7 @@ void main() {
|
||||||
Reference(columnName: 'email'),
|
Reference(columnName: 'email'),
|
||||||
],
|
],
|
||||||
clause: ForeignKeyClause(
|
clause: ForeignKeyClause(
|
||||||
foreignTable: TableReference('another', null),
|
foreignTable: TableReference('another'),
|
||||||
columnNames: [
|
columnNames: [
|
||||||
Reference(columnName: 'a'),
|
Reference(columnName: 'a'),
|
||||||
Reference(columnName: 'b'),
|
Reference(columnName: 'b'),
|
||||||
|
|
|
@ -9,7 +9,7 @@ void main() {
|
||||||
testStatement(
|
testStatement(
|
||||||
'DELETE FROM tbl WHERE id = 5',
|
'DELETE FROM tbl WHERE id = 5',
|
||||||
DeleteStatement(
|
DeleteStatement(
|
||||||
from: TableReference('tbl', null),
|
from: TableReference('tbl'),
|
||||||
where: BinaryExpression(
|
where: BinaryExpression(
|
||||||
Reference(columnName: 'id'),
|
Reference(columnName: 'id'),
|
||||||
token(TokenType.equal),
|
token(TokenType.equal),
|
||||||
|
@ -26,7 +26,7 @@ void main() {
|
||||||
testStatement(
|
testStatement(
|
||||||
'DELETE FROM tbl RETURNING *;',
|
'DELETE FROM tbl RETURNING *;',
|
||||||
DeleteStatement(
|
DeleteStatement(
|
||||||
from: TableReference('tbl', null),
|
from: TableReference('tbl'),
|
||||||
returning: Returning([StarResultColumn()]),
|
returning: Returning([StarResultColumn()]),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|
|
@ -106,7 +106,7 @@ final Map<String, Expression> _testCases = {
|
||||||
ExistsExpression(
|
ExistsExpression(
|
||||||
select: SelectStatement(
|
select: SelectStatement(
|
||||||
columns: [StarResultColumn(null)],
|
columns: [StarResultColumn(null)],
|
||||||
from: TableReference('demo', null),
|
from: TableReference('demo'),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
@ -141,7 +141,7 @@ final Map<String, Expression> _testCases = {
|
||||||
expression: Reference(columnName: 'col'),
|
expression: Reference(columnName: 'col'),
|
||||||
)
|
)
|
||||||
],
|
],
|
||||||
from: TableReference('tbl', null),
|
from: TableReference('tbl'),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
@ -192,6 +192,13 @@ final Map<String, Expression> _testCases = {
|
||||||
'RAISE(IGNORE)': RaiseExpression(RaiseKind.ignore),
|
'RAISE(IGNORE)': RaiseExpression(RaiseKind.ignore),
|
||||||
"RAISE(ROLLBACK, 'Not allowed')":
|
"RAISE(ROLLBACK, 'Not allowed')":
|
||||||
RaiseExpression(RaiseKind.rollback, 'Not allowed'),
|
RaiseExpression(RaiseKind.rollback, 'Not allowed'),
|
||||||
|
'foo': Reference(columnName: 'foo'),
|
||||||
|
'foo.bar': Reference(entityName: 'foo', columnName: 'bar'),
|
||||||
|
'foo.bar.baz': Reference(
|
||||||
|
schemaName: 'foo',
|
||||||
|
entityName: 'bar',
|
||||||
|
columnName: 'baz',
|
||||||
|
),
|
||||||
};
|
};
|
||||||
|
|
||||||
void main() {
|
void main() {
|
||||||
|
|
|
@ -9,7 +9,7 @@ void main() {
|
||||||
r'SELECT * FROM tbl LIMIT $limit',
|
r'SELECT * FROM tbl LIMIT $limit',
|
||||||
SelectStatement(
|
SelectStatement(
|
||||||
columns: [StarResultColumn(null)],
|
columns: [StarResultColumn(null)],
|
||||||
from: TableReference('tbl', null),
|
from: TableReference('tbl'),
|
||||||
limit: DartLimitPlaceholder(name: 'limit'),
|
limit: DartLimitPlaceholder(name: 'limit'),
|
||||||
),
|
),
|
||||||
moorMode: true,
|
moorMode: true,
|
||||||
|
@ -21,7 +21,7 @@ void main() {
|
||||||
r'SELECT * FROM tbl LIMIT $amount OFFSET 3',
|
r'SELECT * FROM tbl LIMIT $amount OFFSET 3',
|
||||||
SelectStatement(
|
SelectStatement(
|
||||||
columns: [StarResultColumn(null)],
|
columns: [StarResultColumn(null)],
|
||||||
from: TableReference('tbl', null),
|
from: TableReference('tbl'),
|
||||||
limit: Limit(
|
limit: Limit(
|
||||||
count: DartExpressionPlaceholder(name: 'amount'),
|
count: DartExpressionPlaceholder(name: 'amount'),
|
||||||
offsetSeparator: token(TokenType.offset),
|
offsetSeparator: token(TokenType.offset),
|
||||||
|
@ -37,7 +37,7 @@ void main() {
|
||||||
r'SELECT * FROM tbl ORDER BY $term, $expr DESC',
|
r'SELECT * FROM tbl ORDER BY $term, $expr DESC',
|
||||||
SelectStatement(
|
SelectStatement(
|
||||||
columns: [StarResultColumn(null)],
|
columns: [StarResultColumn(null)],
|
||||||
from: TableReference('tbl', null),
|
from: TableReference('tbl'),
|
||||||
orderBy: OrderBy(
|
orderBy: OrderBy(
|
||||||
terms: [
|
terms: [
|
||||||
DartOrderingTermPlaceholder(name: 'term'),
|
DartOrderingTermPlaceholder(name: 'term'),
|
||||||
|
@ -57,7 +57,7 @@ void main() {
|
||||||
r'SELECT * FROM tbl ORDER BY $order',
|
r'SELECT * FROM tbl ORDER BY $order',
|
||||||
SelectStatement(
|
SelectStatement(
|
||||||
columns: [StarResultColumn(null)],
|
columns: [StarResultColumn(null)],
|
||||||
from: TableReference('tbl', null),
|
from: TableReference('tbl'),
|
||||||
orderBy: DartOrderByPlaceholder(name: 'order'),
|
orderBy: DartOrderByPlaceholder(name: 'order'),
|
||||||
),
|
),
|
||||||
moorMode: true,
|
moorMode: true,
|
||||||
|
|
|
@ -9,7 +9,7 @@ void main() {
|
||||||
'INSERT OR REPLACE INTO tbl (a, b, c) VALUES (d, e, f)',
|
'INSERT OR REPLACE INTO tbl (a, b, c) VALUES (d, e, f)',
|
||||||
InsertStatement(
|
InsertStatement(
|
||||||
mode: InsertMode.insertOrReplace,
|
mode: InsertMode.insertOrReplace,
|
||||||
table: TableReference('tbl', null),
|
table: TableReference('tbl'),
|
||||||
targetColumns: [
|
targetColumns: [
|
||||||
Reference(columnName: 'a'),
|
Reference(columnName: 'a'),
|
||||||
Reference(columnName: 'b'),
|
Reference(columnName: 'b'),
|
||||||
|
@ -31,7 +31,7 @@ void main() {
|
||||||
'INSERT INTO tbl DEFAULT VALUES',
|
'INSERT INTO tbl DEFAULT VALUES',
|
||||||
InsertStatement(
|
InsertStatement(
|
||||||
mode: InsertMode.insert,
|
mode: InsertMode.insert,
|
||||||
table: TableReference('tbl', null),
|
table: TableReference('tbl'),
|
||||||
targetColumns: const [],
|
targetColumns: const [],
|
||||||
source: DefaultValues(),
|
source: DefaultValues(),
|
||||||
),
|
),
|
||||||
|
@ -43,12 +43,12 @@ void main() {
|
||||||
'REPLACE INTO tbl SELECT * FROM tbl',
|
'REPLACE INTO tbl SELECT * FROM tbl',
|
||||||
InsertStatement(
|
InsertStatement(
|
||||||
mode: InsertMode.replace,
|
mode: InsertMode.replace,
|
||||||
table: TableReference('tbl', null),
|
table: TableReference('tbl'),
|
||||||
targetColumns: const [],
|
targetColumns: const [],
|
||||||
source: SelectInsertSource(
|
source: SelectInsertSource(
|
||||||
SelectStatement(
|
SelectStatement(
|
||||||
columns: [StarResultColumn(null)],
|
columns: [StarResultColumn(null)],
|
||||||
from: TableReference('tbl', null),
|
from: TableReference('tbl'),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
|
|
@ -46,7 +46,7 @@ void main() {
|
||||||
ForeignKeyColumnConstraint(
|
ForeignKeyColumnConstraint(
|
||||||
null,
|
null,
|
||||||
ForeignKeyClause(
|
ForeignKeyClause(
|
||||||
foreignTable: TableReference('other', null),
|
foreignTable: TableReference('other'),
|
||||||
columnNames: [
|
columnNames: [
|
||||||
Reference(columnName: 'location'),
|
Reference(columnName: 'location'),
|
||||||
],
|
],
|
||||||
|
@ -62,7 +62,7 @@ void main() {
|
||||||
SimpleName('all'),
|
SimpleName('all'),
|
||||||
SelectStatement(
|
SelectStatement(
|
||||||
columns: [StarResultColumn(null)],
|
columns: [StarResultColumn(null)],
|
||||||
from: TableReference('tbl', null),
|
from: TableReference('tbl'),
|
||||||
where: DartExpressionPlaceholder(name: 'predicate'),
|
where: DartExpressionPlaceholder(name: 'predicate'),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
@ -70,7 +70,7 @@ void main() {
|
||||||
SpecialStatementIdentifier('special'),
|
SpecialStatementIdentifier('special'),
|
||||||
SelectStatement(
|
SelectStatement(
|
||||||
columns: [StarResultColumn(null)],
|
columns: [StarResultColumn(null)],
|
||||||
from: TableReference('tbl', null),
|
from: TableReference('tbl'),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
DeclaredStatement(
|
DeclaredStatement(
|
||||||
|
@ -104,7 +104,7 @@ void main() {
|
||||||
SimpleName('nested'),
|
SimpleName('nested'),
|
||||||
SelectStatement(
|
SelectStatement(
|
||||||
columns: [NestedStarResultColumn('foo')],
|
columns: [NestedStarResultColumn('foo')],
|
||||||
from: TableReference('tbl', 'foo'),
|
from: TableReference('tbl', as: 'foo'),
|
||||||
),
|
),
|
||||||
as: 'MyResultSet',
|
as: 'MyResultSet',
|
||||||
),
|
),
|
||||||
|
|
|
@ -16,7 +16,7 @@ void main() {
|
||||||
DeclaredStatement(
|
DeclaredStatement(
|
||||||
SimpleName('a'),
|
SimpleName('a'),
|
||||||
UpdateStatement(
|
UpdateStatement(
|
||||||
table: TableReference('tbl', null),
|
table: TableReference('tbl'),
|
||||||
set: [
|
set: [
|
||||||
SetComponent(
|
SetComponent(
|
||||||
column: Reference(columnName: 'a'),
|
column: Reference(columnName: 'a'),
|
||||||
|
@ -29,7 +29,7 @@ void main() {
|
||||||
SimpleName('b'),
|
SimpleName('b'),
|
||||||
SelectStatement(
|
SelectStatement(
|
||||||
columns: [StarResultColumn(null)],
|
columns: [StarResultColumn(null)],
|
||||||
from: TableReference('tbl', null),
|
from: TableReference('tbl'),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
]),
|
]),
|
||||||
|
@ -48,7 +48,7 @@ void main() {
|
||||||
SimpleName('b'),
|
SimpleName('b'),
|
||||||
SelectStatement(
|
SelectStatement(
|
||||||
columns: [StarResultColumn(null)],
|
columns: [StarResultColumn(null)],
|
||||||
from: TableReference('tbl', null),
|
from: TableReference('tbl'),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
@ -78,7 +78,7 @@ void main() {
|
||||||
SimpleName('query'),
|
SimpleName('query'),
|
||||||
SelectStatement(
|
SelectStatement(
|
||||||
columns: [StarResultColumn(null)],
|
columns: [StarResultColumn(null)],
|
||||||
from: TableReference('tbl', null),
|
from: TableReference('tbl'),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|
|
@ -47,7 +47,7 @@ void main() {
|
||||||
and n.folderId = :selectedFolderId;
|
and n.folderId = :selectedFolderId;
|
||||||
''',
|
''',
|
||||||
SelectStatement(
|
SelectStatement(
|
||||||
from: TableReference('notes', 'n'),
|
from: TableReference('notes', as: 'n'),
|
||||||
columns: [StarResultColumn()],
|
columns: [StarResultColumn()],
|
||||||
where: BinaryExpression(
|
where: BinaryExpression(
|
||||||
caseExpr,
|
caseExpr,
|
||||||
|
@ -69,7 +69,7 @@ void main() {
|
||||||
END;
|
END;
|
||||||
''',
|
''',
|
||||||
SelectStatement(
|
SelectStatement(
|
||||||
from: TableReference('notes', 'n'),
|
from: TableReference('notes', as: 'n'),
|
||||||
columns: [StarResultColumn()],
|
columns: [StarResultColumn()],
|
||||||
where: BinaryExpression(
|
where: BinaryExpression(
|
||||||
folderExpr,
|
folderExpr,
|
||||||
|
|
|
@ -10,7 +10,7 @@ void main() {
|
||||||
CompoundSelectStatement(
|
CompoundSelectStatement(
|
||||||
base: SelectStatement(
|
base: SelectStatement(
|
||||||
columns: [StarResultColumn(null)],
|
columns: [StarResultColumn(null)],
|
||||||
from: TableReference('tbl', null),
|
from: TableReference('tbl'),
|
||||||
),
|
),
|
||||||
additional: [
|
additional: [
|
||||||
CompoundSelectPart(
|
CompoundSelectPart(
|
||||||
|
|
|
@ -16,7 +16,13 @@ void main() {
|
||||||
final stmt =
|
final stmt =
|
||||||
SqlEngine().parse('SELECT * FROM tbl').rootNode as SelectStatement;
|
SqlEngine().parse('SELECT * FROM tbl').rootNode as SelectStatement;
|
||||||
|
|
||||||
enforceEqual(stmt.from!, TableReference('tbl', null));
|
_enforceFrom(stmt, TableReference('tbl'));
|
||||||
|
});
|
||||||
|
|
||||||
|
test('schema name and alias', () {
|
||||||
|
final stmt = SqlEngine().parse('SELECT * FROM main.tbl foo').rootNode
|
||||||
|
as SelectStatement;
|
||||||
|
_enforceFrom(stmt, TableReference('tbl', schemaName: 'main', as: 'foo'));
|
||||||
});
|
});
|
||||||
|
|
||||||
test('from more than one table', () {
|
test('from more than one table', () {
|
||||||
|
@ -27,11 +33,11 @@ void main() {
|
||||||
_enforceFrom(
|
_enforceFrom(
|
||||||
stmt,
|
stmt,
|
||||||
JoinClause(
|
JoinClause(
|
||||||
primary: TableReference('tbl', 'test'),
|
primary: TableReference('tbl', as: 'test'),
|
||||||
joins: [
|
joins: [
|
||||||
Join(
|
Join(
|
||||||
operator: JoinOperator.comma,
|
operator: JoinOperator.comma,
|
||||||
query: TableReference('table2', null),
|
query: TableReference('table2'),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
|
@ -46,11 +52,11 @@ void main() {
|
||||||
_enforceFrom(
|
_enforceFrom(
|
||||||
stmt,
|
stmt,
|
||||||
JoinClause(
|
JoinClause(
|
||||||
primary: TableReference('tbl', 'test'),
|
primary: TableReference('tbl', as: 'test'),
|
||||||
joins: [
|
joins: [
|
||||||
Join(
|
Join(
|
||||||
operator: JoinOperator.comma,
|
operator: JoinOperator.comma,
|
||||||
query: TableReference('table2', null),
|
query: TableReference('table2'),
|
||||||
constraint: OnConstraint(
|
constraint: OnConstraint(
|
||||||
expression: BooleanLiteral.withTrue(token(TokenType.$true)),
|
expression: BooleanLiteral.withTrue(token(TokenType.$true)),
|
||||||
),
|
),
|
||||||
|
@ -69,14 +75,14 @@ void main() {
|
||||||
_enforceFrom(
|
_enforceFrom(
|
||||||
stmt,
|
stmt,
|
||||||
JoinClause(
|
JoinClause(
|
||||||
primary: TableReference('table1', null),
|
primary: TableReference('table1'),
|
||||||
joins: [
|
joins: [
|
||||||
Join(
|
Join(
|
||||||
operator: JoinOperator.comma,
|
operator: JoinOperator.comma,
|
||||||
query: SelectStatementAsSource(
|
query: SelectStatementAsSource(
|
||||||
statement: SelectStatement(
|
statement: SelectStatement(
|
||||||
columns: [StarResultColumn(null)],
|
columns: [StarResultColumn(null)],
|
||||||
from: TableReference('table2', null),
|
from: TableReference('table2'),
|
||||||
where: Reference(columnName: 'a'),
|
where: Reference(columnName: 'a'),
|
||||||
),
|
),
|
||||||
as: 'inner',
|
as: 'inner',
|
||||||
|
@ -132,16 +138,16 @@ void main() {
|
||||||
_enforceFrom(
|
_enforceFrom(
|
||||||
stmt,
|
stmt,
|
||||||
JoinClause(
|
JoinClause(
|
||||||
primary: TableReference('table1', null),
|
primary: TableReference('table1'),
|
||||||
joins: [
|
joins: [
|
||||||
Join(
|
Join(
|
||||||
operator: JoinOperator.inner,
|
operator: JoinOperator.inner,
|
||||||
query: TableReference('table2', null),
|
query: TableReference('table2'),
|
||||||
constraint: UsingConstraint(columnNames: ['test']),
|
constraint: UsingConstraint(columnNames: ['test']),
|
||||||
),
|
),
|
||||||
Join(
|
Join(
|
||||||
operator: JoinOperator.leftOuter,
|
operator: JoinOperator.leftOuter,
|
||||||
query: TableReference('table3', null),
|
query: TableReference('table3'),
|
||||||
constraint: OnConstraint(
|
constraint: OnConstraint(
|
||||||
expression: BooleanLiteral.withTrue(token(TokenType.$true)),
|
expression: BooleanLiteral.withTrue(token(TokenType.$true)),
|
||||||
),
|
),
|
||||||
|
|
|
@ -32,16 +32,16 @@ final Map<String, AstNode> testCases = {
|
||||||
expression: SubQuery(
|
expression: SubQuery(
|
||||||
select: SelectStatement(
|
select: SelectStatement(
|
||||||
columns: [StarResultColumn(null)],
|
columns: [StarResultColumn(null)],
|
||||||
from: TableReference('table2', null),
|
from: TableReference('table2'),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
from: TableReference('tbl', null),
|
from: TableReference('tbl'),
|
||||||
),
|
),
|
||||||
'SELECT * FROM tbl WHERE id IN ()': SelectStatement(
|
'SELECT * FROM tbl WHERE id IN ()': SelectStatement(
|
||||||
columns: [StarResultColumn(null)],
|
columns: [StarResultColumn(null)],
|
||||||
from: TableReference('tbl', null),
|
from: TableReference('tbl'),
|
||||||
where: InExpression(
|
where: InExpression(
|
||||||
left: Reference(columnName: 'id'),
|
left: Reference(columnName: 'id'),
|
||||||
inside: Tuple(expressions: []),
|
inside: Tuple(expressions: []),
|
||||||
|
|
|
@ -6,7 +6,7 @@ import 'utils.dart';
|
||||||
final Map<String, AstNode> testCases = {
|
final Map<String, AstNode> testCases = {
|
||||||
'UPDATE OR ROLLBACK tbl SET a = NULL, b = c WHERE d': UpdateStatement(
|
'UPDATE OR ROLLBACK tbl SET a = NULL, b = c WHERE d': UpdateStatement(
|
||||||
or: FailureMode.rollback,
|
or: FailureMode.rollback,
|
||||||
table: TableReference('tbl', null),
|
table: TableReference('tbl'),
|
||||||
set: [
|
set: [
|
||||||
SetComponent(
|
SetComponent(
|
||||||
column: Reference(columnName: 'a'),
|
column: Reference(columnName: 'a'),
|
||||||
|
|
|
@ -221,6 +221,11 @@ CREATE UNIQUE INDEX my_idx ON t1 (c1, c2, c3) WHERE c1 < c3;
|
||||||
''');
|
''');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test('table references', () {
|
||||||
|
testFormat('SELECT * FROM foo');
|
||||||
|
testFormat('SELECT * FROM main.foo');
|
||||||
|
});
|
||||||
|
|
||||||
test('limit', () {
|
test('limit', () {
|
||||||
testFormat('SELECT * FROM foo LIMIT 3, 4');
|
testFormat('SELECT * FROM foo LIMIT 3, 4');
|
||||||
testFormat('SELECT * FROM foo LIMIT 4 OFFSET 3');
|
testFormat('SELECT * FROM foo LIMIT 4 OFFSET 3');
|
||||||
|
@ -379,6 +384,12 @@ CREATE UNIQUE INDEX my_idx ON t1 (c1, c2, c3) WHERE c1 < c3;
|
||||||
test('unary expression', () {
|
test('unary expression', () {
|
||||||
testFormat('SELECT -(+(~3));');
|
testFormat('SELECT -(+(~3));');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test('references', () {
|
||||||
|
testFormat('SELECT foo');
|
||||||
|
testFormat('SELECT foo.bar');
|
||||||
|
testFormat('SELECT foo.bar.baz');
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
group('moor', () {
|
group('moor', () {
|
||||||
|
|
Loading…
Reference in New Issue