returning<R> method
Adds a row-returning projection to this mutation.
The result type exposes only row-returning terminals, so RETURNING statements cannot accidentally use SqlExecutor.execute. MySQL rejects this operation before any database call.
Implementation
SqlRead<R> returning<R>(SqlProjection<R> projection) {
final dialect = statement.dialect!;
if (!supportsSqlReturning(dialect)) {
throw const SqlException(
SqlErrorCode.unsupported,
'MySQL does not support SQL RETURNING in this query layer.',
);
}
for (final selection in projection.columns) {
final column = selection._source;
if (!identical(column.table, _table)) {
throw ArgumentError(
'Returning column "${column.name}" does not belong to '
'table "${_table.name}".',
);
}
}
final fragments = List<String>.of(statement.fragments);
final suffix = StringBuffer(' RETURNING ');
for (final (index, selection) in projection.columns.indexed) {
if (index != 0) suffix.write(', ');
final column = selection._source;
suffix.write(dialect.quoteIdentifier(column.name));
final resultName = selection._resultColumn.name;
if (resultName != column.name) {
suffix
..write(' AS ')
..write(dialect.quoteIdentifier(resultName));
}
}
fragments[fragments.length - 1] = '${fragments.last}${suffix.toString()}';
return SqlRead<R>._(
BoundSql.parts(
fragments,
statement.values,
kind: SqlStatementKind.rowReturning,
dialect: dialect,
),
projection.decode,
);
}