mirror of https://github.com/AMT-Cheif/drift.git
sqlparser: Make InsertSource an AstNode
This commit is contained in:
parent
7ae3783473
commit
5c6331e486
|
@ -2,7 +2,7 @@
|
|||
|
||||
- Breaking: Made `RecursiveVisitor.visit`, `visitList` and `visitExcept` an extension on `AstVisitor`.
|
||||
- Support the transformer pattern to modify ast nodes
|
||||
- Breaking: `FrameBoundary`, `DeleteTarget`, `UpdateTarget` and `InsertTarget` are no longer constant
|
||||
- Breaking: `FrameBoundary`, `DeleteTarget`, `UpdateTarget`, `DefaultValues` and `InsertTarget` are no longer constant
|
||||
- Support parsing and analyzing `CREATE VIEW` statements (see `SchemaFromCreateTable.readView`).
|
||||
Thanks to [@mqus](https://github.com/mqus) for their contribution!
|
||||
|
||||
|
|
|
@ -48,13 +48,13 @@ class InsertStatement extends CrudStatement {
|
|||
}
|
||||
|
||||
@override
|
||||
Iterable<AstNode> get childNodes sync* {
|
||||
if (withClause != null) yield withClause;
|
||||
yield table;
|
||||
yield* targetColumns;
|
||||
yield* source.childNodes;
|
||||
if (upsert != null) yield upsert;
|
||||
}
|
||||
Iterable<AstNode> get childNodes => [
|
||||
if (withClause != null) withClause,
|
||||
table,
|
||||
...targetColumns,
|
||||
source,
|
||||
if (upsert != null) upsert
|
||||
];
|
||||
|
||||
@override
|
||||
bool contentEquals(InsertStatement other) {
|
||||
|
@ -62,12 +62,7 @@ class InsertStatement extends CrudStatement {
|
|||
}
|
||||
}
|
||||
|
||||
// todo: Should be an AstNode
|
||||
abstract class InsertSource {
|
||||
Iterable<AstNode> get childNodes;
|
||||
|
||||
const InsertSource();
|
||||
|
||||
abstract class InsertSource extends AstNode {
|
||||
T when<T>(
|
||||
{T Function(ValuesSource) isValues,
|
||||
T Function(SelectInsertSource) isSelect,
|
||||
|
@ -92,22 +87,57 @@ class ValuesSource extends InsertSource {
|
|||
|
||||
@override
|
||||
Iterable<AstNode> get childNodes => values;
|
||||
|
||||
@override
|
||||
R accept<A, R>(AstVisitor<A, R> visitor, A arg) {
|
||||
return visitor.visitValuesSource(this, arg);
|
||||
}
|
||||
|
||||
@override
|
||||
bool contentEquals(ValuesSource other) => true;
|
||||
|
||||
@override
|
||||
void transformChildren<A>(Transformer<A> transformer, A arg) {
|
||||
transformer.transformChildren(values, this, arg);
|
||||
}
|
||||
}
|
||||
|
||||
/// Inserts the rows returned by [stmt].
|
||||
class SelectInsertSource extends InsertSource {
|
||||
final BaseSelectStatement stmt;
|
||||
BaseSelectStatement stmt;
|
||||
|
||||
SelectInsertSource(this.stmt);
|
||||
|
||||
@override
|
||||
Iterable<AstNode> get childNodes => [stmt];
|
||||
|
||||
@override
|
||||
R accept<A, R>(AstVisitor<A, R> visitor, A arg) {
|
||||
return visitor.visitSelectInsertSource(this, arg);
|
||||
}
|
||||
|
||||
@override
|
||||
bool contentEquals(SelectInsertSource other) => true;
|
||||
|
||||
@override
|
||||
void transformChildren<A>(Transformer<A> transformer, A arg) {
|
||||
stmt = transformer.transformChild(stmt, this, arg);
|
||||
}
|
||||
}
|
||||
|
||||
/// Use `DEFAULT VALUES` for an insert statement.
|
||||
class DefaultValues extends InsertSource {
|
||||
const DefaultValues();
|
||||
|
||||
@override
|
||||
Iterable<AstNode> get childNodes => const [];
|
||||
|
||||
@override
|
||||
R accept<A, R>(AstVisitor<A, R> visitor, A arg) {
|
||||
return visitor.visitDefaultValues(this, arg);
|
||||
}
|
||||
|
||||
@override
|
||||
bool contentEquals(DefaultValues other) => true;
|
||||
|
||||
@override
|
||||
void transformChildren<A>(Transformer<A> transformer, A arg) {}
|
||||
}
|
||||
|
|
|
@ -34,6 +34,10 @@ abstract class AstVisitor<A, R> {
|
|||
|
||||
R visitSetComponent(SetComponent e, A arg);
|
||||
|
||||
R visitValuesSource(ValuesSource e, A arg);
|
||||
R visitSelectInsertSource(SelectInsertSource e, A arg);
|
||||
R visitDefaultValues(DefaultValues e, A arg);
|
||||
|
||||
R visitColumnDefinition(ColumnDefinition e, A arg);
|
||||
R visitColumnConstraint(ColumnConstraint e, A arg);
|
||||
R visitTableConstraint(TableConstraint e, A arg);
|
||||
|
@ -257,6 +261,25 @@ class RecursiveVisitor<A, R> implements AstVisitor<A, R> {
|
|||
return defaultNode(e, arg);
|
||||
}
|
||||
|
||||
@override
|
||||
R visitValuesSource(ValuesSource e, A arg) {
|
||||
return defaultInsertSource(e, arg);
|
||||
}
|
||||
|
||||
@override
|
||||
R visitSelectInsertSource(SelectInsertSource e, A arg) {
|
||||
return defaultInsertSource(e, arg);
|
||||
}
|
||||
|
||||
@override
|
||||
R visitDefaultValues(DefaultValues e, A arg) {
|
||||
return defaultInsertSource(e, arg);
|
||||
}
|
||||
|
||||
R defaultInsertSource(InsertSource e, A arg) {
|
||||
return defaultNode(e, arg);
|
||||
}
|
||||
|
||||
@override
|
||||
R visitColumnDefinition(ColumnDefinition e, A arg) {
|
||||
return defaultNode(e, arg);
|
||||
|
|
|
@ -667,18 +667,23 @@ mixin CrudParser on ParserBase {
|
|||
|
||||
InsertSource _insertSource() {
|
||||
if (_matchOne(TokenType.$values)) {
|
||||
final first = _previous;
|
||||
final values = <Tuple>[];
|
||||
do {
|
||||
// it will be a tuple, we don't turn on "orSubQuery"
|
||||
values.add(_consumeTuple() as Tuple);
|
||||
} while (_matchOne(TokenType.comma));
|
||||
return ValuesSource(values);
|
||||
|
||||
return ValuesSource(values)..setSpan(first, _previous);
|
||||
} else if (_matchOne(TokenType.$default)) {
|
||||
final first = _previous;
|
||||
_consume(TokenType.$values, 'Expected DEFAULT VALUES');
|
||||
return const DefaultValues();
|
||||
return DefaultValues()..setSpan(first, _previous);
|
||||
} else {
|
||||
final first = _previous;
|
||||
return SelectInsertSource(
|
||||
_fullSelect() ?? _error('Expeced a select statement'));
|
||||
_fullSelect() ?? _error('Expeced a select statement'),
|
||||
)..setSpan(first, _previous);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -33,7 +33,7 @@ void main() {
|
|||
mode: InsertMode.insert,
|
||||
table: TableReference('tbl', null),
|
||||
targetColumns: const [],
|
||||
source: const DefaultValues(),
|
||||
source: DefaultValues(),
|
||||
),
|
||||
);
|
||||
});
|
||||
|
@ -63,7 +63,7 @@ void main() {
|
|||
InsertStatement(
|
||||
table: TableReference('tbl'),
|
||||
targetColumns: const [],
|
||||
source: const DefaultValues(),
|
||||
source: DefaultValues(),
|
||||
upsert: UpsertClause(action: DoNothing()),
|
||||
),
|
||||
);
|
||||
|
@ -75,7 +75,7 @@ void main() {
|
|||
InsertStatement(
|
||||
table: TableReference('tbl'),
|
||||
targetColumns: const [],
|
||||
source: const DefaultValues(),
|
||||
source: DefaultValues(),
|
||||
upsert: UpsertClause(
|
||||
onColumns: [
|
||||
IndexedColumn(Reference(columnName: 'foo')),
|
||||
|
@ -96,7 +96,7 @@ void main() {
|
|||
InsertStatement(
|
||||
table: TableReference('tbl'),
|
||||
targetColumns: const [],
|
||||
source: const DefaultValues(),
|
||||
source: DefaultValues(),
|
||||
upsert: UpsertClause(
|
||||
onColumns: [
|
||||
IndexedColumn(Reference(columnName: 'foo')),
|
||||
|
@ -119,7 +119,7 @@ void main() {
|
|||
InsertStatement(
|
||||
table: TableReference('tbl'),
|
||||
targetColumns: const [],
|
||||
source: const DefaultValues(),
|
||||
source: DefaultValues(),
|
||||
upsert: UpsertClause(
|
||||
action: DoUpdate(
|
||||
[
|
||||
|
@ -140,7 +140,7 @@ void main() {
|
|||
InsertStatement(
|
||||
table: TableReference('tbl'),
|
||||
targetColumns: const [],
|
||||
source: const DefaultValues(),
|
||||
source: DefaultValues(),
|
||||
upsert: UpsertClause(
|
||||
action: DoUpdate(
|
||||
[
|
||||
|
|
Loading…
Reference in New Issue