@@ -49,26 +49,26 @@ func TestPgSqlParser_Redact(t *testing.T) {
4949 sql : `WITH active_users AS (
5050 SELECT * FROM users WHERE last_login > '2024-01-01'
5151 ), recent_orders AS (
52- SELECT o.* FROM orders o
53- JOIN active_users u ON u.id = o.user_id
52+ SELECT o.* FROM orders o
53+ JOIN active_users u ON u.id = o.user_id
5454 WHERE o.created_at > '2024-03-01'
5555 )
56- SELECT au.name, COUNT(ro.id) as order_count
57- FROM active_users au
58- LEFT JOIN recent_orders ro ON ro.user_id = au.id
59- GROUP BY au.name
56+ SELECT au.name, COUNT(ro.id) as order_count
57+ FROM active_users au
58+ LEFT JOIN recent_orders ro ON ro.user_id = au.id
59+ GROUP BY au.name
6060 HAVING COUNT(ro.id) > 5` ,
6161 want : `WITH active_users AS (
6262 SELECT * FROM users WHERE last_login > ?
6363 ), recent_orders AS (
64- SELECT o.* FROM orders o
65- JOIN active_users u ON u.id = o.user_id
64+ SELECT o.* FROM orders o
65+ JOIN active_users u ON u.id = o.user_id
6666 WHERE o.created_at > ?
6767 )
68- SELECT au.name, COUNT(ro.id) as order_count
69- FROM active_users au
70- LEFT JOIN recent_orders ro ON ro.user_id = au.id
71- GROUP BY au.name
68+ SELECT au.name, COUNT(ro.id) as order_count
69+ FROM active_users au
70+ LEFT JOIN recent_orders ro ON ro.user_id = au.id
71+ GROUP BY au.name
7272 HAVING COUNT(ro.id) > ?` ,
7373 },
7474 {
@@ -106,13 +106,13 @@ func TestPgSqlParser_Redact(t *testing.T) {
106106 {
107107 name : "WITH statement with UPDATE" ,
108108 sql : `WITH inactive_users AS (
109- SELECT id FROM users
109+ SELECT id FROM users
110110 WHERE last_login < '2023-01-01' AND status = 'active'
111111 )
112112 UPDATE users SET status = 'inactive', updated_at = '2024-03-20'
113113 WHERE id IN (SELECT id FROM inactive_users)` ,
114114 want : `WITH inactive_users AS (
115- SELECT id FROM users
115+ SELECT id FROM users
116116 WHERE last_login < ? AND status = ?
117117 )
118118 UPDATE users SET status = ?, updated_at = ?
@@ -121,16 +121,16 @@ func TestPgSqlParser_Redact(t *testing.T) {
121121 {
122122 name : "WITH statement with DELETE" ,
123123 sql : `WITH old_orders AS (
124- SELECT id FROM orders
124+ SELECT id FROM orders
125125 WHERE created_at < '2023-01-01' AND status = 'completed'
126126 )
127- DELETE FROM order_items
127+ DELETE FROM order_items
128128 WHERE order_id IN (SELECT id FROM old_orders)` ,
129129 want : `WITH old_orders AS (
130- SELECT id FROM orders
130+ SELECT id FROM orders
131131 WHERE created_at < ? AND status = ?
132132 )
133- DELETE FROM order_items
133+ DELETE FROM order_items
134134 WHERE order_id IN (SELECT id FROM old_orders)` ,
135135 },
136136 {
@@ -185,134 +185,6 @@ func TestPgSqlParser_Redact(t *testing.T) {
185185 }
186186}
187187
188- func TestPgSqlParser_ExtractTableNames (t * testing.T ) {
189- tests := []struct {
190- name string
191- sql string
192- want []string
193- wantErr bool
194- }{
195- {
196- name : "simple select" ,
197- sql : "SELECT * FROM users" ,
198- want : []string {"users" },
199- },
200- {
201- name : "select with join" ,
202- sql : "SELECT * FROM users u JOIN orders o ON u.id = o.user_id" ,
203- want : []string {"orders" , "users" },
204- },
205- {
206- name : "select with schema qualified tables" ,
207- sql : "SELECT * FROM public.users JOIN sales.orders ON users.id = orders.user_id" ,
208- want : []string {"public.users" , "sales.orders" },
209- },
210- {
211- name : "insert statement" ,
212- sql :
"INSERT INTO users (name, email) VALUES ('John', '[email protected] ')" ,
213- want : []string {"users" },
214- },
215- {
216- name : "update statement" ,
217- sql : "UPDATE users SET last_login = NOW() WHERE id = 1" ,
218- want : []string {"users" },
219- },
220- {
221- name : "delete statement" ,
222- sql : "DELETE FROM users WHERE id = 1" ,
223- want : []string {"users" },
224- },
225- {
226- name : "with clause" ,
227- sql : `WITH active_users AS (
228- SELECT * FROM users WHERE status = 'active'
229- )
230- SELECT * FROM active_users au
231- JOIN orders o ON o.user_id = au.id` ,
232- want : []string {"orders" , "users" },
233- },
234- {
235- name : "subquery in where clause" ,
236- sql : `SELECT * FROM orders
237- WHERE user_id IN (SELECT id FROM users WHERE status = 'active')` ,
238- want : []string {"orders" , "users" },
239- },
240- {
241- name : "multiple schema qualified tables with aliases" ,
242- sql : `SELECT u.name, o.total, p.status
243- FROM public.users u
244- JOIN sales.orders o ON u.id = o.user_id
245- LEFT JOIN shipping.packages p ON o.id = p.order_id` ,
246- want : []string {"public.users" , "sales.orders" , "shipping.packages" },
247- },
248- {
249- name : "truncated query with ..." ,
250- sql : "SELECT * FROM users JOIN orders ON users.id = orders.user_id AND..." ,
251- want : []string {"users" , "orders" },
252- },
253- {
254- name : "truncated query with incomplete comment" ,
255- sql : "SELECT * FROM users JOIN orders ON users.id = orders.user_id /* some comment that gets truncated..." ,
256- want : []string {"users" , "orders" },
257- },
258- {
259- name : "truncated query mid-table name" ,
260- sql : "SELECT * FROM users JOIN ord..." ,
261- want : []string {"users" , "ord..." },
262- },
263- {
264- name : "truncated query with schema qualified tables" ,
265- sql : "SELECT * FROM public.users JOIN sales.orders ON users.id = orders.user_id AND..." ,
266- want : []string {"public.users" , "sales.orders" },
267- },
268- {
269- name : "query with table.* expression" ,
270- sql : "SELECT u.*, o.* FROM users u JOIN orders o ON u.id = o.user_id" ,
271- want : []string {"users" , "orders" },
272- },
273- {
274- name : "query with type cast" ,
275- sql : "SELECT u.id, '2024-03-20'::timestamp FROM users u" ,
276- want : []string {"users" },
277- },
278- }
279-
280- for _ , tt := range tests {
281- t .Run (tt .name , func (t * testing.T ) {
282- got , err := ExtractTableNames (tt .sql )
283- if (err != nil ) != tt .wantErr {
284- t .Errorf ("ExtractTableNames() error = %v, wantErr %v" , err , tt .wantErr )
285- return
286- }
287- if ! tt .wantErr {
288- if len (got ) != len (tt .want ) {
289- t .Errorf ("ExtractTableNames()\n GOT = %v\n WANT = %v" , got , tt .want )
290- return
291- }
292- // Compare slices ignoring order since table names might come in different order
293- gotMap := make (map [string ]bool )
294- wantMap := make (map [string ]bool )
295- for _ , table := range got {
296- gotMap [table ] = true
297- }
298- for _ , table := range tt .want {
299- wantMap [table ] = true
300- }
301- for table := range gotMap {
302- if ! wantMap [table ] {
303- t .Errorf ("ExtractTableNames() got unexpected table = %v" , table )
304- }
305- }
306- for table := range wantMap {
307- if ! gotMap [table ] {
308- t .Errorf ("ExtractTableNames() missing expected table = %v" , table )
309- }
310- }
311- }
312- })
313- }
314- }
315-
316188func TestContainsReservedKeywords (t * testing.T ) {
317189 tests := []struct {
318190 name string
0 commit comments