Skip to content

Commit

Permalink
Add support for inserts from select queries
Browse files Browse the repository at this point in the history
  • Loading branch information
cachapa committed Feb 16, 2024
1 parent 2594d3a commit 6d0870b
Show file tree
Hide file tree
Showing 3 changed files with 47 additions and 9 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
## 2.1.7

- Add support for inserts from select queries

## 2.1.6

- Upgrade sqlparser
Expand Down
50 changes: 42 additions & 8 deletions lib/src/timestamped_crdt.dart
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,48 @@ abstract class TimestampedCrdt extends BaseCrdt {
@override
Future<void> _insert(InsertStatement statement, List<Object?>? args,
[Hlc? hlc]) async {
// Force explicit column description in insert statements
assert(statement.targetColumns.isNotEmpty,
'Unsupported statement: target columns must be explicitly stated.\n${statement.toSql()}');
// Disallow star select statements
assert(
statement.source is! SelectInsertSource ||
((statement.source as SelectInsertSource).stmt as SelectStatement)
.columns
.whereType<StarResultColumn>()
.isEmpty,
'Unsupported statement: select columns must be explicitly stated.\n${statement.toSql()}');

final argCount = args?.length ?? 0;
final source = switch (statement.source) {
ValuesSource s => ValuesSource([
Tuple(expressions: [
...s.values.first.expressions,
NumberedVariable(argCount + 1),
NumberedVariable(argCount + 2),
NumberedVariable(argCount + 3),
])
]),
SelectInsertSource s => SelectInsertSource(SelectStatement(
withClause: (s.stmt as SelectStatement).withClause,
distinct: (s.stmt as SelectStatement).distinct,
columns: [
...(s.stmt as SelectStatement).columns,
ExpressionResultColumn(expression: NumberedVariable(argCount + 1)),
ExpressionResultColumn(expression: NumberedVariable(argCount + 2)),
ExpressionResultColumn(expression: NumberedVariable(argCount + 3)),
],
from: (s.stmt as SelectStatement).from,
where: (s.stmt as SelectStatement).where,
groupBy: (s.stmt as SelectStatement).groupBy,
windowDeclarations: (s.stmt as SelectStatement).windowDeclarations,
orderBy: (s.stmt as SelectStatement).orderBy,
limit: (s.stmt as SelectStatement).limit,
)),
_ => throw UnimplementedError(
'Unsupported data source: ${statement.source.runtimeType}, please file an issue in the sql_crdt project.')
};

final newStatement = InsertStatement(
mode: statement.mode,
upsert: statement.upsert,
Expand All @@ -23,14 +64,7 @@ abstract class TimestampedCrdt extends BaseCrdt {
Reference(columnName: 'node_id'),
Reference(columnName: 'modified'),
],
source: ValuesSource([
Tuple(expressions: [
...(statement.source as ValuesSource).values.first.expressions,
NumberedVariable(argCount + 1),
NumberedVariable(argCount + 2),
NumberedVariable(argCount + 3),
])
]),
source: source,
);

// Touch
Expand Down
2 changes: 1 addition & 1 deletion pubspec.yaml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
name: sql_crdt
description: Base package for Conflict-free Replicated Data Types (CRDTs) using SQL databases
version: 2.1.6
version: 2.1.7
homepage: https://github.com/cachapa/sql_crdt
repository: https://github.com/cachapa/sql_crdt
issue_tracker: https://github.com/cachapa/sql_crdt/issues
Expand Down

0 comments on commit 6d0870b

Please sign in to comment.