use diesel::{ dsl, expression::{is_aggregate, ValidGrouping}, pg::Pg, query_builder::{AsQuery, AstPass, QueryFragment}, result::Error, sql_types, AppearsOnTable, Expression, Insertable, QueryId, SelectableExpression, }; /// Gererates a series of rows for insertion. /// /// An inclusive range is created from `start` and `stop`. A row for each number is generated using `selection`, which can be a tuple. /// [`current_value`] is an expression that gets the current value. /// /// For example, if there's a `numbers` table with a `number` column, this inserts all numbers from 1 to 10 in a single statement: /// /// ``` /// dsl::insert_into(numbers::table) /// .values(ValuesFromSeries { /// start: 1, /// stop: 10, /// selection: series::current_value, /// }) /// .into_columns(numbers::number) /// ``` #[derive(QueryId)] pub struct ValuesFromSeries { pub start: i64, pub stop: i64, pub selection: S, } impl> QueryFragment for ValuesFromSeries { fn walk_ast<'b>(&'b self, mut out: AstPass<'_, 'b, Pg>) -> Result<(), Error> { self.selection.walk_ast(out.reborrow())?; out.push_sql(" FROM generate_series("); out.push_bind_param::(&self.start)?; out.push_sql(", "); out.push_bind_param::(&self.stop)?; out.push_sql(")"); Ok(()) } } impl Expression for ValuesFromSeries { type SqlType = S::SqlType; } impl> AppearsOnTable for ValuesFromSeries {} impl> SelectableExpression for ValuesFromSeries {} impl> Insertable for ValuesFromSeries where dsl::BareSelect: AsQuery + Insertable, { type Values = as Insertable>::Values; fn values(self) -> Self::Values { dsl::select(self).values() } } impl> ValidGrouping<()> for ValuesFromSeries { type IsAggregate = is_aggregate::No; } #[allow(non_camel_case_types)] #[derive(QueryId, Clone, Copy, Debug)] pub struct current_value; impl QueryFragment for current_value { fn walk_ast<'b>(&'b self, mut out: AstPass<'_, 'b, Pg>) -> Result<(), Error> { out.push_identifier("generate_series")?; Ok(()) } } impl Expression for current_value { type SqlType = sql_types::BigInt; } impl AppearsOnTable for current_value {} impl SelectableExpression for current_value {} impl ValidGrouping<()> for current_value { type IsAggregate = is_aggregate::No; }