Skip to content

Commit 6b37df3

Browse files
authored
delete with using statement fix (#248)
* fix * fix * more test cases
1 parent d41b8eb commit 6b37df3

File tree

5 files changed

+334
-5
lines changed

5 files changed

+334
-5
lines changed

src/ts_generator/sql_parser/translate_delete.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,18 +2,19 @@ use crate::core::connection::DBConn;
22
use crate::ts_generator::errors::TsGeneratorError;
33
use crate::ts_generator::sql_parser::expressions::translate_expr::translate_expr;
44
use crate::ts_generator::types::ts_query::TsQuery;
5-
use sqlparser::ast::Expr;
5+
use sqlparser::ast::{Expr, TableWithJoins};
66

77
pub async fn translate_delete(
88
ts_query: &mut TsQuery,
99
where_conditions: &Expr, // WHERE conditions of the delete statement
1010
table_name: &str,
11+
table_with_joins: &Option<Vec<TableWithJoins>>, // Includes FROM and USING tables
1112
db_conn: &DBConn,
1213
) -> Result<(), TsGeneratorError> {
1314
translate_expr(
1415
where_conditions,
1516
&Some(table_name),
16-
&None,
17+
table_with_joins,
1718
None,
1819
ts_query,
1920
db_conn,

src/ts_generator/sql_parser/translate_stmt.rs

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,15 @@ pub async fn translate_stmt(
5252
let table_name = get_default_table(from);
5353
let table_name_str = table_name.as_str();
5454
let selection = delete.selection.to_owned().unwrap();
55-
translate_delete(ts_query, &selection, table_name_str, db_conn).await?;
55+
56+
// Build a combined Vec<TableWithJoins> that includes both FROM and USING tables
57+
let mut all_tables = from.to_vec();
58+
if let Some(using_tables) = &delete.using {
59+
all_tables.extend(using_tables.clone());
60+
}
61+
let table_with_joins = if all_tables.is_empty() { None } else { Some(all_tables) };
62+
63+
translate_delete(ts_query, &selection, table_name_str, &table_with_joins, db_conn).await?;
5664

5765
// Handle RETURNING clause if present
5866
if delete.returning.is_some() {

tests/mysql_delete_query_parameters.rs

Lines changed: 137 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,12 +56,148 @@ r#"
5656
export type SomeDeleteQueryParams = [number, number];
5757
5858
export interface ISomeDeleteQueryResult {
59-
59+
6060
}
6161
6262
export interface ISomeDeleteQueryQuery {
6363
params: SomeDeleteQueryParams;
6464
result: ISomeDeleteQueryResult;
6565
}
66+
"#);
67+
68+
#[rustfmt::skip]
69+
run_test!(should_handle_delete_with_join_using_aliases, TestConfig::new("mysql", true, None, None),
70+
71+
//// TS query ////
72+
r#"
73+
const deleteInventory = sql`
74+
DELETE inv FROM inventory inv
75+
INNER JOIN characters c ON inv.character_id = c.id
76+
WHERE c.id = ?
77+
AND inv.id = ?;
78+
`
79+
"#,
80+
81+
//// Generated TS interfaces ////
82+
r#"
83+
export type DeleteInventoryParams = [number, number];
84+
85+
export interface IDeleteInventoryResult {
86+
87+
}
88+
89+
export interface IDeleteInventoryQuery {
90+
params: DeleteInventoryParams;
91+
result: IDeleteInventoryResult;
92+
}
93+
"#);
94+
95+
#[rustfmt::skip]
96+
run_test!(should_handle_delete_with_multiple_joins, TestConfig::new("mysql", true, None, None),
97+
98+
//// TS query ////
99+
r#"
100+
const deleteItems = sql`
101+
DELETE i FROM items i
102+
INNER JOIN inventory inv ON i.inventory_id = inv.id
103+
INNER JOIN characters c ON inv.character_id = c.id
104+
WHERE c.id = ?
105+
AND i.rarity = ?;
106+
`
107+
"#,
108+
109+
//// Generated TS interfaces ////
110+
r#"
111+
export type DeleteItemsParams = [number, string | null];
112+
113+
export interface IDeleteItemsResult {
114+
115+
}
116+
117+
export interface IDeleteItemsQuery {
118+
params: DeleteItemsParams;
119+
result: IDeleteItemsResult;
120+
}
121+
"#);
122+
123+
#[rustfmt::skip]
124+
run_test!(should_handle_delete_with_left_join, TestConfig::new("mysql", true, None, None),
125+
126+
//// TS query ////
127+
r#"
128+
const deleteByCharacter = sql`
129+
DELETE inv FROM inventory inv
130+
LEFT JOIN characters c ON inv.character_id = c.id
131+
WHERE c.id = ?
132+
AND inv.quantity = 0;
133+
`
134+
"#,
135+
136+
//// Generated TS interfaces ////
137+
r#"
138+
export type DeleteByCharacterParams = [number];
139+
140+
export interface IDeleteByCharacterResult {
141+
142+
}
143+
144+
export interface IDeleteByCharacterQuery {
145+
params: DeleteByCharacterParams;
146+
result: IDeleteByCharacterResult;
147+
}
148+
"#);
149+
150+
#[rustfmt::skip]
151+
run_test!(should_handle_delete_with_comparison_and_join, TestConfig::new("mysql", true, None, None),
152+
153+
//// TS query ////
154+
r#"
155+
const deleteByQuantity = sql`
156+
DELETE inv FROM inventory inv
157+
INNER JOIN items i ON i.inventory_id = inv.id
158+
WHERE i.rarity = ?
159+
AND inv.quantity < ?;
160+
`
161+
"#,
162+
163+
//// Generated TS interfaces ////
164+
r#"
165+
export type DeleteByQuantityParams = [string | null, number | null];
166+
167+
export interface IDeleteByQuantityResult {
168+
169+
}
170+
171+
export interface IDeleteByQuantityQuery {
172+
params: DeleteByQuantityParams;
173+
result: IDeleteByQuantityResult;
174+
}
175+
"#);
176+
177+
#[rustfmt::skip]
178+
run_test!(should_handle_delete_with_or_conditions_and_join, TestConfig::new("mysql", true, None, None),
179+
180+
//// TS query ////
181+
r#"
182+
const deleteConditional = sql`
183+
DELETE inv FROM inventory inv
184+
INNER JOIN characters c ON inv.character_id = c.id
185+
WHERE (c.id = ? OR c.name = ?)
186+
AND inv.quantity = 0;
187+
`
188+
"#,
189+
190+
//// Generated TS interfaces ////
191+
r#"
192+
export type DeleteConditionalParams = [number, string];
193+
194+
export interface IDeleteConditionalResult {
195+
196+
}
197+
198+
export interface IDeleteConditionalQuery {
199+
params: DeleteConditionalParams;
200+
result: IDeleteConditionalResult;
201+
}
66202
"#);
67203
}

tests/postgres_delete_query_parameters.rs

Lines changed: 141 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,12 +56,152 @@ r#"
5656
export type SomeDeleteQueryParams = [number, number];
5757
5858
export interface ISomeDeleteQueryResult {
59-
59+
6060
}
6161
6262
export interface ISomeDeleteQueryQuery {
6363
params: SomeDeleteQueryParams;
6464
result: ISomeDeleteQueryResult;
6565
}
66+
"#);
67+
68+
#[rustfmt::skip]
69+
run_test!(should_handle_delete_using_with_aliases, TestConfig::new("postgres", true, None, None),
70+
71+
//// TS query ////
72+
r#"
73+
const deleteInventory = sql`
74+
DELETE FROM inventory inv
75+
USING characters c
76+
WHERE inv.character_id = c.id
77+
AND c.id = $1
78+
AND inv.id = $2;
79+
`
80+
"#,
81+
82+
//// Generated TS interfaces ////
83+
r#"
84+
export type DeleteInventoryParams = [number, number];
85+
86+
export interface IDeleteInventoryResult {
87+
88+
}
89+
90+
export interface IDeleteInventoryQuery {
91+
params: DeleteInventoryParams;
92+
result: IDeleteInventoryResult;
93+
}
94+
"#);
95+
96+
#[rustfmt::skip]
97+
run_test!(should_handle_delete_using_with_multiple_tables, TestConfig::new("postgres", true, None, None),
98+
99+
//// TS query ////
100+
r#"
101+
const deleteItems = sql`
102+
DELETE FROM items i
103+
USING inventory inv, characters c
104+
WHERE i.inventory_id = inv.id
105+
AND inv.character_id = c.id
106+
AND c.id = $1
107+
AND i.rarity = $2;
108+
`
109+
"#,
110+
111+
//// Generated TS interfaces ////
112+
r#"
113+
export type DeleteItemsParams = [number, string | null];
114+
115+
export interface IDeleteItemsResult {
116+
117+
}
118+
119+
export interface IDeleteItemsQuery {
120+
params: DeleteItemsParams;
121+
result: IDeleteItemsResult;
122+
}
123+
"#);
124+
125+
#[rustfmt::skip]
126+
run_test!(should_handle_delete_using_with_comparison, TestConfig::new("postgres", true, None, None),
127+
128+
//// TS query ////
129+
r#"
130+
const deleteOldInventory = sql`
131+
DELETE FROM inventory inv
132+
USING characters c
133+
WHERE inv.character_id = c.id
134+
AND c.id = $1
135+
AND inv.quantity > $2;
136+
`
137+
"#,
138+
139+
//// Generated TS interfaces ////
140+
r#"
141+
export type DeleteOldInventoryParams = [number, number | null];
142+
143+
export interface IDeleteOldInventoryResult {
144+
145+
}
146+
147+
export interface IDeleteOldInventoryQuery {
148+
params: DeleteOldInventoryParams;
149+
result: IDeleteOldInventoryResult;
150+
}
151+
"#);
152+
153+
#[rustfmt::skip]
154+
run_test!(should_handle_delete_using_with_in_clause, TestConfig::new("postgres", true, None, None),
155+
156+
//// TS query ////
157+
r#"
158+
const deleteByRarity = sql`
159+
DELETE FROM inventory inv
160+
USING items i
161+
WHERE i.inventory_id = inv.id
162+
AND i.rarity = $1;
163+
`
164+
"#,
165+
166+
//// Generated TS interfaces ////
167+
r#"
168+
export type DeleteByRarityParams = [string | null];
169+
170+
export interface IDeleteByRarityResult {
171+
172+
}
173+
174+
export interface IDeleteByRarityQuery {
175+
params: DeleteByRarityParams;
176+
result: IDeleteByRarityResult;
177+
}
178+
"#);
179+
180+
#[rustfmt::skip]
181+
run_test!(should_handle_delete_using_with_or_conditions, TestConfig::new("postgres", true, None, None),
182+
183+
//// TS query ////
184+
r#"
185+
const deleteConditional = sql`
186+
DELETE FROM inventory inv
187+
USING characters c
188+
WHERE inv.character_id = c.id
189+
AND (c.id = $1 OR c.name = $2)
190+
AND inv.quantity = 0;
191+
`
192+
"#,
193+
194+
//// Generated TS interfaces ////
195+
r#"
196+
export type DeleteConditionalParams = [number, string];
197+
198+
export interface IDeleteConditionalResult {
199+
200+
}
201+
202+
export interface IDeleteConditionalQuery {
203+
params: DeleteConditionalParams;
204+
result: IDeleteConditionalResult;
205+
}
66206
"#);
67207
}

tests/sample/sample.queries.ts

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
export type SampleSelectQueryParams = [number];
2+
3+
export interface ISampleSelectQueryResult {
4+
name: string;
5+
some_id: number;
6+
}
7+
8+
export interface ISampleSelectQueryQuery {
9+
params: SampleSelectQueryParams;
10+
result: ISampleSelectQueryResult;
11+
}
12+
13+
export type SampleInsertQueryParams = [string];
14+
15+
export interface ISampleInsertQueryResult {
16+
17+
}
18+
19+
export interface ISampleInsertQueryQuery {
20+
params: SampleInsertQueryParams;
21+
result: ISampleInsertQueryResult;
22+
}
23+
24+
export type SampleUpdateQueryParams = [string, number];
25+
26+
export interface ISampleUpdateQueryResult {
27+
28+
}
29+
30+
export interface ISampleUpdateQueryQuery {
31+
params: SampleUpdateQueryParams;
32+
result: ISampleUpdateQueryResult;
33+
}
34+
35+
export type SampleDeleteQueryParams = [number];
36+
37+
export interface ISampleDeleteQueryResult {
38+
39+
}
40+
41+
export interface ISampleDeleteQueryQuery {
42+
params: SampleDeleteQueryParams;
43+
result: ISampleDeleteQueryResult;
44+
}

0 commit comments

Comments
 (0)