Skip to content

Commit

Permalink
Merge pull request SeaQL#252 from SeaQL/pull/223
Browse files Browse the repository at this point in the history
Insert Default (SeaQL#223)
  • Loading branch information
tyt2y3 authored Feb 6, 2022
2 parents 81285b9 + 2678211 commit f60ee3a
Show file tree
Hide file tree
Showing 6 changed files with 143 additions and 65 deletions.
4 changes: 4 additions & 0 deletions src/backend/mysql/query.rs
Original file line number Diff line number Diff line change
Expand Up @@ -56,4 +56,8 @@ impl QueryBuilder for MysqlQueryBuilder {
) {
// MySQL doesn't support declaring materialization in SQL for with query.
}

fn insert_default_keyword(&self) -> &str {
"VALUES (DEFAULT)"
}
}
63 changes: 36 additions & 27 deletions src/backend/query_builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,39 +22,43 @@ pub trait QueryBuilder: QuotedBuilder {
write!(sql, " ").unwrap();
}

write!(sql, "(").unwrap();
insert.columns.iter().fold(true, |first, col| {
if !first {
write!(sql, ", ").unwrap()
}
col.prepare(sql, self.quote());
false
});
write!(sql, ")").unwrap();
if insert.columns.is_empty() && insert.source.is_none() {
write!(sql, "{}", self.insert_default_keyword()).unwrap();
} else {
write!(sql, "(").unwrap();
insert.columns.iter().fold(true, |first, col| {
if !first {
write!(sql, ", ").unwrap()
}
col.prepare(sql, self.quote());
false
});
write!(sql, ")").unwrap();

if let Some(source) = &insert.source {
write!(sql, " ").unwrap();
match source {
InsertValueSource::Values(values) => {
write!(sql, "VALUES ").unwrap();
values.iter().fold(true, |first, row| {
if !first {
write!(sql, ", ").unwrap()
}
write!(sql, "(").unwrap();
row.iter().fold(true, |first, col| {
if let Some(source) = &insert.source {
write!(sql, " ").unwrap();
match source {
InsertValueSource::Values(values) => {
write!(sql, "VALUES ").unwrap();
values.iter().fold(true, |first, row| {
if !first {
write!(sql, ", ").unwrap()
}
self.prepare_simple_expr(col, sql, collector);
write!(sql, "(").unwrap();
row.iter().fold(true, |first, col| {
if !first {
write!(sql, ", ").unwrap()
}
self.prepare_simple_expr(col, sql, collector);
false
});
write!(sql, ")").unwrap();
false
});
write!(sql, ")").unwrap();
false
});
}
InsertValueSource::Select(select_query) => {
self.prepare_select_statement(select_query.deref(), sql, collector);
}
InsertValueSource::Select(select_query) => {
self.prepare_select_statement(select_query.deref(), sql, collector);
}
}
}
}
Expand Down Expand Up @@ -1164,6 +1168,11 @@ pub trait QueryBuilder: QuotedBuilder {
fn char_length_function(&self) -> &str {
"CHAR_LENGTH"
}

/// The keywords for insert default statement (insert without explicit values)
fn insert_default_keyword(&self) -> &str {
"DEFAULT VALUES"
}
}

impl SubQueryStatement {
Expand Down
20 changes: 11 additions & 9 deletions src/query/insert.rs
Original file line number Diff line number Diff line change
Expand Up @@ -231,17 +231,19 @@ impl InsertStatement {
val_len: values.len(),
});
}
let values_source = if let Some(InsertValueSource::Values(values)) = &mut self.source {
values
} else {
self.source = Some(InsertValueSource::Values(Default::default()));
if let Some(InsertValueSource::Values(values)) = &mut self.source {
if !values.is_empty() {
let values_source = if let Some(InsertValueSource::Values(values)) = &mut self.source {
values
} else {
unreachable!();
}
};
values_source.push(values);
self.source = Some(InsertValueSource::Values(Default::default()));
if let Some(InsertValueSource::Values(values)) = &mut self.source {
values
} else {
unreachable!();
}
};
values_source.push(values);
}
Ok(self)
}

Expand Down
21 changes: 21 additions & 0 deletions tests/mysql/query.rs
Original file line number Diff line number Diff line change
Expand Up @@ -967,6 +967,27 @@ fn insert_5() {
);
}

#[test]
fn insert_6() {
assert_eq!(
Query::insert()
.into_table(Glyph::Table)
.to_string(MysqlQueryBuilder),
"INSERT INTO `glyph` VALUES (DEFAULT)"
);
}

#[test]
fn insert_7() {
assert_eq!(
Query::insert()
.into_table(Glyph::Table)
.returning_col(Glyph::Id)
.to_string(MysqlQueryBuilder),
"INSERT INTO `glyph` VALUES (DEFAULT)"
);
}

#[test]
fn insert_from_select() {
assert_eq!(
Expand Down
79 changes: 50 additions & 29 deletions tests/postgres/query.rs
Original file line number Diff line number Diff line change
Expand Up @@ -936,35 +936,6 @@ fn insert_5() {
);
}

#[test]
fn insert_from_select() {
assert_eq!(
Query::insert()
.into_table(Glyph::Table)
.columns(vec![Glyph::Aspect, Glyph::Image])
.select_from(
Query::select()
.column(Glyph::Aspect)
.column(Glyph::Image)
.from(Glyph::Table)
.conditions(
true,
|x| {
x.and_where(Expr::col(Glyph::Image).like("%"));
},
|x| {
x.and_where(Expr::col(Glyph::Id).eq(6));
},
)
.to_owned()
)
.unwrap()
.to_owned()
.to_string(PostgresQueryBuilder),
r#"INSERT INTO "glyph" ("aspect", "image") SELECT "aspect", "image" FROM "glyph" WHERE "image" LIKE '%'"#
);
}

#[test]
fn insert_6() -> sea_query::error::Result<()> {
let select = SelectStatement::new()
Expand Down Expand Up @@ -999,6 +970,56 @@ fn insert_6() -> sea_query::error::Result<()> {
Ok(())
}

#[test]
fn insert_7() {
assert_eq!(
Query::insert()
.into_table(Glyph::Table)
.to_string(PostgresQueryBuilder),
"INSERT INTO \"glyph\" DEFAULT VALUES"
);
}

#[test]
fn insert_8() {
assert_eq!(
Query::insert()
.into_table(Glyph::Table)
.returning_col(Glyph::Id)
.to_string(PostgresQueryBuilder),
"INSERT INTO \"glyph\" DEFAULT VALUES RETURNING \"id\""
);
}

#[test]
fn insert_from_select() {
assert_eq!(
Query::insert()
.into_table(Glyph::Table)
.columns(vec![Glyph::Aspect, Glyph::Image])
.select_from(
Query::select()
.column(Glyph::Aspect)
.column(Glyph::Image)
.from(Glyph::Table)
.conditions(
true,
|x| {
x.and_where(Expr::col(Glyph::Image).like("%"));
},
|x| {
x.and_where(Expr::col(Glyph::Id).eq(6));
},
)
.to_owned()
)
.unwrap()
.to_owned()
.to_string(PostgresQueryBuilder),
r#"INSERT INTO "glyph" ("aspect", "image") SELECT "aspect", "image" FROM "glyph" WHERE "image" LIKE '%'"#
);
}

#[test]
fn update_1() {
assert_eq!(
Expand Down
21 changes: 21 additions & 0 deletions tests/sqlite/query.rs
Original file line number Diff line number Diff line change
Expand Up @@ -965,6 +965,27 @@ fn insert_5() {
);
}

#[test]
fn insert_6() {
assert_eq!(
Query::insert()
.into_table(Glyph::Table)
.to_string(SqliteQueryBuilder),
r#"INSERT INTO "glyph" DEFAULT VALUES"#
);
}

#[test]
fn insert_7() {
assert_eq!(
Query::insert()
.into_table(Glyph::Table)
.returning_col(Glyph::Id)
.to_string(SqliteQueryBuilder),
r#"INSERT INTO "glyph" DEFAULT VALUES RETURNING "id""#
);
}

#[test]
fn update_1() {
assert_eq!(
Expand Down

0 comments on commit f60ee3a

Please sign in to comment.