diff --git a/src/backend/query_builder.rs b/src/backend/query_builder.rs index 22f0f08fb..fc1c15b21 100644 --- a/src/backend/query_builder.rs +++ b/src/backend/query_builder.rs @@ -251,6 +251,13 @@ pub trait QueryBuilder: QuotedBuilder { write!(sql, ".").unwrap(); column.prepare(sql, self.quote()); } + ColumnRef::Asterisk => { + write!(sql, "*").unwrap(); + } + ColumnRef::TableAsterisk(table) => { + table.prepare(sql, self.quote()); + write!(sql, ".*").unwrap(); + } }; } SimpleExpr::Tuple(exprs) => { diff --git a/src/expr.rs b/src/expr.rs index 595964479..4446d2a04 100644 --- a/src/expr.rs +++ b/src/expr.rs @@ -53,6 +53,58 @@ impl Expr { } } + /// Express the asterisk without table prefix. + /// + /// # Examples + /// + /// ``` + /// use sea_query::{tests_cfg::*, *}; + /// + /// let query = Query::select() + /// .expr(Expr::asterisk()) + /// .from(Char::Table) + /// .to_owned(); + /// + /// assert_eq!( + /// query.to_string(MysqlQueryBuilder), + /// r#"SELECT * FROM `character`"# + /// ); + /// assert_eq!( + /// query.to_string(PostgresQueryBuilder), + /// r#"SELECT * FROM "character""# + /// ); + /// assert_eq!( + /// query.to_string(SqliteQueryBuilder), + /// r#"SELECT * FROM `character`"# + /// ); + /// ``` + /// + /// ``` + /// use sea_query::{tests_cfg::*, *}; + /// + /// let query = Query::select() + /// .columns(vec![Char::Character, Char::SizeW, Char::SizeH]) + /// .from(Char::Table) + /// .and_where(Expr::col((Char::Table, Char::SizeW)).eq(1)) + /// .to_owned(); + /// + /// assert_eq!( + /// query.to_string(MysqlQueryBuilder), + /// r#"SELECT `character`, `size_w`, `size_h` FROM `character` WHERE `character`.`size_w` = 1"# + /// ); + /// assert_eq!( + /// query.to_string(PostgresQueryBuilder), + /// r#"SELECT "character", "size_w", "size_h" FROM "character" WHERE "character"."size_w" = 1"# + /// ); + /// assert_eq!( + /// query.to_string(SqliteQueryBuilder), + /// r#"SELECT `character`, `size_w`, `size_h` FROM `character` WHERE `character`.`size_w` = 1"# + /// ); + /// ``` + pub fn asterisk() -> Self { + Self::col(ColumnRef::Asterisk) + } + /// Express the target column without table prefix. /// /// # Examples @@ -146,6 +198,62 @@ impl Expr { )) } + /// Express the asterisk with table prefix. + /// + /// # Examples + /// + /// ``` + /// use sea_query::{tests_cfg::*, *}; + /// + /// let query = Query::select() + /// .expr(Expr::asterisk()) + /// .from(Char::Table) + /// .to_owned(); + /// + /// assert_eq!( + /// query.to_string(MysqlQueryBuilder), + /// r#"SELECT * FROM `character`"# + /// ); + /// assert_eq!( + /// query.to_string(PostgresQueryBuilder), + /// r#"SELECT * FROM "character""# + /// ); + /// assert_eq!( + /// query.to_string(SqliteQueryBuilder), + /// r#"SELECT * FROM `character`"# + /// ); + /// ``` + /// + /// ``` + /// use sea_query::{tests_cfg::*, *}; + /// + /// let query = Query::select() + /// .expr(Expr::tbl_asterisk(Char::Table)) + /// .column((Font::Table, Font::Name)) + /// .from(Char::Table) + /// .inner_join(Font::Table, Expr::tbl(Char::Table, Char::FontId).equals(Font::Table, Font::Id)) + /// .to_owned(); + /// + /// assert_eq!( + /// query.to_string(MysqlQueryBuilder), + /// r#"SELECT `character`.*, `font`.`name` FROM `character` INNER JOIN `font` ON `character`.`font_id` = `font`.`id`"# + /// ); + /// assert_eq!( + /// query.to_string(PostgresQueryBuilder), + /// r#"SELECT "character".*, "font"."name" FROM "character" INNER JOIN "font" ON "character"."font_id" = "font"."id""# + /// ); + /// assert_eq!( + /// query.to_string(SqliteQueryBuilder), + /// r#"SELECT `character`.*, `font`.`name` FROM `character` INNER JOIN `font` ON `character`.`font_id` = `font`.`id`"# + /// ); + /// ``` + pub fn tbl_asterisk(t: T) -> Self + where + T: IntoIden + { + Self::col(ColumnRef::TableAsterisk(t.into_iden())) + } + /// Express the target column with table prefix. /// /// # Examples diff --git a/src/types.rs b/src/types.rs index 2136afa38..421a85150 100644 --- a/src/types.rs +++ b/src/types.rs @@ -63,6 +63,8 @@ pub enum ColumnRef { Column(DynIden), TableColumn(DynIden, DynIden), SchemaTableColumn(DynIden, DynIden, DynIden), + Asterisk, + TableAsterisk(DynIden) } pub trait IntoColumnRef { diff --git a/tests/mysql/query.rs b/tests/mysql/query.rs index 4a8e241a7..9f6294f5a 100644 --- a/tests/mysql/query.rs +++ b/tests/mysql/query.rs @@ -790,6 +790,34 @@ fn select_48() { ); } +#[test] +fn select_49() { + let statement = sea_query::Query::select() + .expr(Expr::asterisk()) + .from(Char::Table) + .to_string(MysqlQueryBuilder); + + assert_eq!( + statement, + r#"SELECT * FROM `character`"# + ); +} + +#[test] +fn select_50() { + let statement = sea_query::Query::select() + .expr(Expr::tbl_asterisk(Char::Table)) + .column((Font::Table, Font::Name)) + .from(Char::Table) + .inner_join(Font::Table, Expr::tbl(Char::Table, Char::FontId).equals(Font::Table, Font::Id)) + .to_string(MysqlQueryBuilder); + + assert_eq!( + statement, + r#"SELECT `character`.*, `font`.`name` FROM `character` INNER JOIN `font` ON `character`.`font_id` = `font`.`id`"# + ); +} + #[test] #[allow(clippy::approx_constant)] fn insert_2() { diff --git a/tests/postgres/query.rs b/tests/postgres/query.rs index e06d21d89..53e0394fc 100644 --- a/tests/postgres/query.rs +++ b/tests/postgres/query.rs @@ -774,6 +774,34 @@ fn select_48() { ); } +#[test] +fn select_49() { + let statement = sea_query::Query::select() + .expr(Expr::asterisk()) + .from(Char::Table) + .to_string(PostgresQueryBuilder); + + assert_eq!( + statement, + r#"SELECT * FROM "character""# + ); +} + +#[test] +fn select_50() { + let statement = sea_query::Query::select() + .expr(Expr::tbl_asterisk(Char::Table)) + .column((Font::Table, Font::Name)) + .from(Char::Table) + .inner_join(Font::Table, Expr::tbl(Char::Table, Char::FontId).equals(Font::Table, Font::Id)) + .to_string(PostgresQueryBuilder); + + assert_eq!( + statement, + r#"SELECT "character".*, "font"."name" FROM "character" INNER JOIN "font" ON "character"."font_id" = "font"."id""# + ); +} + #[test] #[allow(clippy::approx_constant)] fn insert_2() { diff --git a/tests/sqlite/query.rs b/tests/sqlite/query.rs index 5110a11e2..819bfde95 100644 --- a/tests/sqlite/query.rs +++ b/tests/sqlite/query.rs @@ -790,6 +790,34 @@ fn select_48() { ); } +#[test] +fn select_49() { + let statement = sea_query::Query::select() + .expr(Expr::asterisk()) + .from(Char::Table) + .to_string(SqliteQueryBuilder); + + assert_eq!( + statement, + r#"SELECT * FROM `character`"# + ); +} + +#[test] +fn select_50() { + let statement = sea_query::Query::select() + .expr(Expr::tbl_asterisk(Char::Table)) + .column((Font::Table, Font::Name)) + .from(Char::Table) + .inner_join(Font::Table, Expr::tbl(Char::Table, Char::FontId).equals(Font::Table, Font::Id)) + .to_string(SqliteQueryBuilder); + + assert_eq!( + statement, + r#"SELECT `character`.*, `font`.`name` FROM `character` INNER JOIN `font` ON `character`.`font_id` = `font`.`id`"# + ); +} + #[test] #[allow(clippy::approx_constant)] fn insert_2() {