Skip to content

Commit

Permalink
Merge pull request #505 from ikrivosheev/fix/issues-485_empty_conditi…
Browse files Browse the repository at this point in the history
…onal

issues-485 Fix syntax error
  • Loading branch information
ikrivosheev committed Nov 30, 2022
2 parents c705198 + 993a174 commit e291d4b
Show file tree
Hide file tree
Showing 5 changed files with 147 additions and 74 deletions.
29 changes: 19 additions & 10 deletions src/backend/query_builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1204,17 +1204,16 @@ pub trait QueryBuilder: QuotedBuilder + EscapeBuilder + TableRefBuilder {
keyword: &str,
sql: &mut dyn SqlWriter,
) {
if !condition.is_empty() {
write!(sql, " {} ", keyword).unwrap();
}
match &condition.contents {
ConditionHolderContents::Empty => (),
ConditionHolderContents::Chain(conditions) => {
write!(sql, " {} ", keyword).unwrap();
for (i, log_chain_oper) in conditions.iter().enumerate() {
self.prepare_logical_chain_oper(log_chain_oper, i, conditions.len(), sql);
}
}
ConditionHolderContents::Condition(c) => {
write!(sql, " {} ", keyword).unwrap();
self.prepare_condition_where(c, sql);
}
}
Expand All @@ -1224,13 +1223,22 @@ pub trait QueryBuilder: QuotedBuilder + EscapeBuilder + TableRefBuilder {
/// Translate part of a condition to part of a "WHERE" clause.
fn prepare_condition_where(&self, condition: &Condition, sql: &mut dyn SqlWriter) {
if condition.negate {
write!(sql, "NOT (").unwrap();
write!(sql, "NOT ").unwrap()
}
let mut is_first = true;
for cond in &condition.conditions {
if is_first {
is_first = false;
} else {

if condition.is_empty() {
match condition.condition_type {
ConditionType::All => self.prepare_constant(&true.into(), sql),
ConditionType::Any => self.prepare_constant(&false.into(), sql),
}
return;
}

if condition.negate {
write!(sql, "(").unwrap();
}
condition.conditions.iter().fold(true, |first, cond| {
if !first {
match condition.condition_type {
ConditionType::Any => write!(sql, " OR ").unwrap(),
ConditionType::All => write!(sql, " AND ").unwrap(),
Expand All @@ -1256,7 +1264,8 @@ pub trait QueryBuilder: QuotedBuilder + EscapeBuilder + TableRefBuilder {
}
}
}
}
false
});
if condition.negate {
write!(sql, ")").unwrap();
}
Expand Down
11 changes: 3 additions & 8 deletions src/query/condition.rs
Original file line number Diff line number Diff line change
Expand Up @@ -71,10 +71,6 @@ impl Condition {
{
let mut expr: ConditionExpression = condition.into();
if let ConditionExpression::Condition(ref mut c) = expr {
// Don't add empty `Condition::any` and `Condition::all`.
if c.conditions.is_empty() {
return self;
}
// Skip the junction if there is only one.
if c.conditions.len() == 1 && !c.negate {
expr = c.conditions.pop().unwrap();
Expand Down Expand Up @@ -185,7 +181,7 @@ impl Condition {
/// # Examples
///
/// ```
/// use sea_query::{*, tests_cfg::*};
/// use sea_query::{tests_cfg::*, *};
///
/// let query = Query::select()
/// .column(Glyph::Image)
Expand Down Expand Up @@ -592,9 +588,8 @@ impl ConditionHolder {
}

pub fn new_with_condition(condition: Condition) -> Self {
let mut slf = Self::new();
slf.add_condition(condition);
slf
let contents = ConditionHolderContents::Condition(condition);
Self { contents }
}

pub fn is_empty(&self) -> bool {
Expand Down
73 changes: 48 additions & 25 deletions tests/mysql/query.rs
Original file line number Diff line number Diff line change
Expand Up @@ -510,11 +510,11 @@ fn select_34a() {

#[test]
fn select_35() {
let (statement, values) = sea_query::Query::select()
let (statement, values) = Query::select()
.column(Glyph::Id)
.from(Glyph::Table)
.and_where(Expr::col(Glyph::Aspect).is_null())
.build(sea_query::MysqlQueryBuilder);
.build(MysqlQueryBuilder);

assert_eq!(
statement,
Expand All @@ -525,11 +525,11 @@ fn select_35() {

#[test]
fn select_36() {
let (statement, values) = sea_query::Query::select()
let (statement, values) = Query::select()
.column(Glyph::Id)
.from(Glyph::Table)
.cond_where(Cond::any().add(Expr::col(Glyph::Aspect).is_null()))
.build(sea_query::MysqlQueryBuilder);
.build(MysqlQueryBuilder);

assert_eq!(
statement,
Expand All @@ -540,27 +540,50 @@ fn select_36() {

#[test]
fn select_37() {
let (statement, values) = sea_query::Query::select()
let (statement, values) = Query::select()
.column(Glyph::Id)
.from(Glyph::Table)
.cond_where(Cond::any().add(Cond::all()).add(Cond::any()))
.build(sea_query::MysqlQueryBuilder);
.build(MysqlQueryBuilder);

assert_eq!(statement, r#"SELECT `id` FROM `glyph`"#);
assert_eq!(
statement,
r#"SELECT `id` FROM `glyph` WHERE (TRUE) OR (FALSE)"#
);
assert_eq!(values.0, vec![]);
}

#[test]
fn select_37a() {
let (statement, values) = Query::select()
.column(Glyph::Id)
.from(Glyph::Table)
.cond_where(
Cond::all()
.add(Cond::all().not())
.add(Cond::any().not())
.not(),
)
.build(MysqlQueryBuilder);

assert_eq!(
statement,
r#"SELECT `id` FROM `glyph` WHERE NOT ((NOT TRUE) AND (NOT FALSE))"#
);
assert_eq!(values.0, vec![]);
}

#[test]
fn select_38() {
let (statement, values) = sea_query::Query::select()
let (statement, values) = Query::select()
.column(Glyph::Id)
.from(Glyph::Table)
.cond_where(
Cond::any()
.add(Expr::col(Glyph::Aspect).is_null())
.add(Expr::col(Glyph::Aspect).is_not_null()),
)
.build(sea_query::MysqlQueryBuilder);
.build(MysqlQueryBuilder);

assert_eq!(
statement,
Expand All @@ -571,15 +594,15 @@ fn select_38() {

#[test]
fn select_39() {
let (statement, values) = sea_query::Query::select()
let (statement, values) = Query::select()
.column(Glyph::Id)
.from(Glyph::Table)
.cond_where(
Cond::all()
.add(Expr::col(Glyph::Aspect).is_null())
.add(Expr::col(Glyph::Aspect).is_not_null()),
)
.build(sea_query::MysqlQueryBuilder);
.build(MysqlQueryBuilder);

assert_eq!(
statement,
Expand All @@ -590,7 +613,7 @@ fn select_39() {

#[test]
fn select_40() {
let statement = sea_query::Query::select()
let statement = Query::select()
.column(Glyph::Id)
.from(Glyph::Table)
.cond_where(any![
Expand All @@ -600,7 +623,7 @@ fn select_40() {
Expr::col(Glyph::Aspect).lt(8)
]
])
.to_string(sea_query::MysqlQueryBuilder);
.to_string(MysqlQueryBuilder);

assert_eq!(
statement,
Expand All @@ -624,7 +647,7 @@ fn select_41() {

#[test]
fn select_42() {
let statement = sea_query::Query::select()
let statement = Query::select()
.column(Glyph::Id)
.from(Glyph::Table)
.cond_where(
Expand All @@ -642,18 +665,18 @@ fn select_42() {

#[test]
fn select_43() {
let statement = sea_query::Query::select()
let statement = Query::select()
.column(Glyph::Id)
.from(Glyph::Table)
.cond_where(Cond::all().add_option::<SimpleExpr>(None))
.to_string(MysqlQueryBuilder);

assert_eq!(statement, "SELECT `id` FROM `glyph`");
assert_eq!(statement, "SELECT `id` FROM `glyph` WHERE TRUE");
}

#[test]
fn select_44() {
let statement = sea_query::Query::select()
let statement = Query::select()
.column(Glyph::Id)
.from(Glyph::Table)
.cond_where(
Expand All @@ -671,7 +694,7 @@ fn select_44() {

#[test]
fn select_45() {
let statement = sea_query::Query::select()
let statement = Query::select()
.column(Glyph::Id)
.from(Glyph::Table)
.cond_where(
Expand All @@ -690,7 +713,7 @@ fn select_45() {

#[test]
fn select_46() {
let statement = sea_query::Query::select()
let statement = Query::select()
.column(Glyph::Id)
.from(Glyph::Table)
.cond_where(
Expand All @@ -708,7 +731,7 @@ fn select_46() {

#[test]
fn select_47() {
let statement = sea_query::Query::select()
let statement = Query::select()
.column(Glyph::Id)
.from(Glyph::Table)
.cond_where(
Expand All @@ -727,7 +750,7 @@ fn select_47() {

#[test]
fn select_48() {
let statement = sea_query::Query::select()
let statement = Query::select()
.column(Glyph::Id)
.from(Glyph::Table)
.cond_where(
Expand All @@ -746,7 +769,7 @@ fn select_48() {

#[test]
fn select_48a() {
let statement = sea_query::Query::select()
let statement = Query::select()
.column(Glyph::Id)
.from(Glyph::Table)
.cond_where(
Expand All @@ -768,7 +791,7 @@ fn select_48a() {

#[test]
fn select_49() {
let statement = sea_query::Query::select()
let statement = Query::select()
.expr(Expr::asterisk())
.from(Char::Table)
.to_string(MysqlQueryBuilder);
Expand All @@ -778,7 +801,7 @@ fn select_49() {

#[test]
fn select_50() {
let statement = sea_query::Query::select()
let statement = Query::select()
.expr(Expr::table_asterisk(Char::Table))
.column((Font::Table, Font::Name))
.from(Char::Table)
Expand Down Expand Up @@ -877,7 +900,7 @@ fn select_53() {

#[test]
fn select_54() {
let statement = sea_query::Query::select()
let statement = Query::select()
.expr(Expr::asterisk())
.from(Char::Table)
.from(Font::Table)
Expand Down
35 changes: 29 additions & 6 deletions tests/postgres/query.rs
Original file line number Diff line number Diff line change
Expand Up @@ -530,7 +530,30 @@ fn select_37() {
.cond_where(Cond::any().add(Cond::all()).add(Cond::any()))
.build(PostgresQueryBuilder);

assert_eq!(statement, r#"SELECT "id" FROM "glyph""#);
assert_eq!(
statement,
r#"SELECT "id" FROM "glyph" WHERE (TRUE) OR (FALSE)"#
);
assert_eq!(values.0, vec![]);
}

#[test]
fn select_37a() {
let (statement, values) = Query::select()
.column(Glyph::Id)
.from(Glyph::Table)
.cond_where(
Cond::all()
.add(Cond::all().not())
.add(Cond::any().not())
.not(),
)
.build(PostgresQueryBuilder);

assert_eq!(
statement,
r#"SELECT "id" FROM "glyph" WHERE NOT ((NOT TRUE) AND (NOT FALSE))"#
);
assert_eq!(values.0, vec![]);
}

Expand All @@ -544,7 +567,7 @@ fn select_38() {
.add(Expr::col(Glyph::Aspect).is_null())
.add(Expr::col(Glyph::Aspect).is_not_null()),
)
.build(sea_query::PostgresQueryBuilder);
.build(PostgresQueryBuilder);

assert_eq!(
statement,
Expand All @@ -555,15 +578,15 @@ fn select_38() {

#[test]
fn select_39() {
let (statement, values) = sea_query::Query::select()
let (statement, values) = Query::select()
.column(Glyph::Id)
.from(Glyph::Table)
.cond_where(
Cond::all()
.add(Expr::col(Glyph::Aspect).is_null())
.add(Expr::col(Glyph::Aspect).is_not_null()),
)
.build(sea_query::PostgresQueryBuilder);
.build(PostgresQueryBuilder);

assert_eq!(
statement,
Expand Down Expand Up @@ -632,7 +655,7 @@ fn select_43() {
.cond_where(Cond::all().add_option::<SimpleExpr>(None))
.to_string(PostgresQueryBuilder);

assert_eq!(statement, r#"SELECT "id" FROM "glyph""#);
assert_eq!(statement, r#"SELECT "id" FROM "glyph" WHERE TRUE"#);
}

#[test]
Expand Down Expand Up @@ -1176,7 +1199,7 @@ fn insert_from_select() {
}

#[test]
fn insert_6() -> sea_query::error::Result<()> {
fn insert_6() -> error::Result<()> {
let select = SelectStatement::new()
.columns([Glyph::Id, Glyph::Image, Glyph::Aspect])
.from(Glyph::Table)
Expand Down
Loading

0 comments on commit e291d4b

Please sign in to comment.