Skip to content

Commit 23b1431

Browse files
authored
Feature flag to have more parentheses (#723)
* Runtime options to have more parentheses * Use Atomic * Use feature flag * clippy * More test
1 parent 6f39795 commit 23b1431

File tree

4 files changed

+94
-2
lines changed

4 files changed

+94
-2
lines changed

.github/workflows/rust.yml

+3-2
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ jobs:
5656
with:
5757
toolchain: stable
5858
components: clippy
59-
- run: cargo clippy --all-features --workspace -- -D warnings
59+
- run: cargo clippy --features=all-features --workspace -- -D warnings
6060
- run: cargo clippy --manifest-path sea-query-binder/Cargo.toml --workspace --features runtime-async-std-rustls --features=with-chrono,with-json,with-rust_decimal,with-bigdecimal,with-uuid,with-time,with-ipnetwork,with-mac_address,postgres-array -- -D warnings
6161
- run: cargo clippy --manifest-path sea-query-rusqlite/Cargo.toml --all-features --workspace -- -D warnings
6262
- run: cargo clippy --manifest-path sea-query-postgres/Cargo.toml --all-features --workspace -- -D warnings
@@ -143,7 +143,8 @@ jobs:
143143
steps:
144144
- uses: actions/checkout@v3
145145
- uses: dtolnay/rust-toolchain@stable
146-
- run: cargo test --all-features
146+
- run: cargo test --features=all-features
147+
- run: cargo test --test test-more-parentheses --features=tests-cfg,option-more-parentheses
147148

148149
derive-test:
149150
name: Derive Tests

Cargo.toml

+28
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,29 @@ with-time = ["time"]
6969
with-ipnetwork = ["ipnetwork"]
7070
with-mac_address = ["mac_address"]
7171
tests-cfg = []
72+
all-features = [
73+
"backend-mysql",
74+
"backend-postgres",
75+
"backend-sqlite",
76+
"derive",
77+
"attr",
78+
"hashable-value",
79+
"thread-safe",
80+
"all-types",
81+
] # everything except option-*
82+
all-types = [
83+
"postgres-array",
84+
"postgres-interval",
85+
"with-chrono",
86+
"with-json",
87+
"with-rust_decimal",
88+
"with-bigdecimal",
89+
"with-uuid",
90+
"with-time",
91+
"with-ipnetwork",
92+
"with-mac_address",
93+
]
94+
option-more-parentheses = []
7295

7396
[[test]]
7497
name = "test-derive"
@@ -95,6 +118,11 @@ name = "test-sqlite"
95118
path = "tests/sqlite/mod.rs"
96119
required-features = ["tests-cfg", "backend-sqlite"]
97120

121+
[[test]]
122+
name = "test-more-parentheses"
123+
path = "tests/more-parentheses.rs"
124+
required-features = ["tests-cfg", "option-more-parentheses", "backend-mysql"]
125+
98126
[[bench]]
99127
name = "basic"
100128
harness = false

src/backend/query_builder.rs

+4
Original file line numberDiff line numberDiff line change
@@ -1533,6 +1533,10 @@ pub(crate) fn common_inner_expr_well_known_greater_precedence(
15331533
| SimpleExpr::Case(_)
15341534
| SimpleExpr::SubQuery(_, _) => true,
15351535
SimpleExpr::Binary(_, inner_oper, _) => {
1536+
#[cfg(feature = "option-more-parentheses")]
1537+
{
1538+
return false;
1539+
}
15361540
let inner_oper: Oper = (*inner_oper).into();
15371541
if inner_oper.is_arithmetic() || inner_oper.is_shift() {
15381542
outer_oper.is_comparison()

tests/more-parentheses.rs

+59
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
use sea_query::{tests_cfg::Glyph, Cond, Expr, MysqlQueryBuilder, Query};
2+
3+
#[test]
4+
fn test_more_parentheses() {
5+
let query = Query::select()
6+
.column(Glyph::Image)
7+
.from(Glyph::Table)
8+
.cond_where(Cond::all())
9+
.cond_where(Expr::val(1).eq(1))
10+
.cond_where(Expr::val(2).eq(2))
11+
.cond_where(Cond::any().add(Expr::val(3).eq(3)).add(Expr::val(4).eq(4)))
12+
.to_owned();
13+
14+
assert_eq!(
15+
query.to_string(MysqlQueryBuilder),
16+
"SELECT `image` FROM `glyph` WHERE (1 = 1) AND (2 = 2) AND ((3 = 3) OR (4 = 4))"
17+
);
18+
}
19+
20+
#[test]
21+
fn test_more_parentheses_complex() {
22+
// Add pagination
23+
let mut pagination = Cond::all();
24+
let lt_value = Expr::col(Glyph::Aspect)
25+
.lt(1)
26+
.or(Expr::col(Glyph::Aspect).is_null());
27+
let lt_id = Expr::col(Glyph::Aspect)
28+
.is(1)
29+
.and(Expr::col(Glyph::Id).lt(10));
30+
pagination = pagination.add(lt_value.or(lt_id));
31+
32+
// Add filtering
33+
let mut all = Cond::all();
34+
all = all.add(Expr::col(Glyph::Image).eq("png"));
35+
36+
let mut nested = Cond::all();
37+
nested = nested.add(Expr::col(Glyph::Table).gte(5));
38+
nested = nested.add(Expr::col(Glyph::Tokens).lte(3));
39+
all = all.add(nested);
40+
41+
let mut any = Cond::any();
42+
any = any.add(Expr::col(Glyph::Image).like("%.jpg"));
43+
any = any.add(all);
44+
let filtering = any;
45+
46+
// Query
47+
let query = Query::select()
48+
.column(Glyph::Id)
49+
.from(Glyph::Table)
50+
.cond_where(Cond::all())
51+
.cond_where(pagination)
52+
.cond_where(filtering)
53+
.to_owned();
54+
55+
assert_eq!(
56+
query.to_string(MysqlQueryBuilder),
57+
"SELECT `id` FROM `glyph` WHERE ((`aspect` < 1) OR (`aspect` IS NULL) OR ((`aspect` IS 1) AND (`id` < 10))) AND ((`image` LIKE '%.jpg') OR ((`image` = 'png') AND ((`glyph` >= 5) AND (`tokens` <= 3))))"
58+
);
59+
}

0 commit comments

Comments
 (0)