@@ -162,3 +162,107 @@ func TestUpdateBuilderGetFlavor(t *testing.T) {
162162 flavor = ubClick .Flavor ()
163163 a .Equal (ClickHouse , flavor )
164164}
165+
166+ func ExampleUpdateBuilder_Returning () {
167+ ub := NewUpdateBuilder ()
168+ ub .Update ("user" )
169+ ub .Set (ub .Assign ("name" , "Huan Du" ))
170+ ub .Where (ub .Equal ("id" , 123 ))
171+ ub .Returning ("id" , "updated_at" )
172+
173+ sql , args := ub .BuildWithFlavor (PostgreSQL )
174+ fmt .Println (sql )
175+ fmt .Println (args )
176+
177+ // Output:
178+ // UPDATE user SET name = $1 WHERE id = $2 RETURNING id, updated_at
179+ // [Huan Du 123]
180+ }
181+
182+ func TestUpdateBuilderReturning (t * testing.T ) {
183+ a := assert .New (t )
184+ ub := NewUpdateBuilder ()
185+ ub .Update ("user" )
186+ ub .Set (ub .Assign ("name" , "Huan Du" ))
187+ ub .Where (ub .Equal ("id" , 123 ))
188+ ub .Returning ("id" , "updated_at" )
189+
190+ sql , _ := ub .BuildWithFlavor (MySQL )
191+ a .Equal ("UPDATE user SET name = ? WHERE id = ?" , sql )
192+
193+ sql , _ = ub .BuildWithFlavor (PostgreSQL )
194+ a .Equal ("UPDATE user SET name = $1 WHERE id = $2 RETURNING id, updated_at" , sql )
195+
196+ sql , _ = ub .BuildWithFlavor (SQLite )
197+ a .Equal ("UPDATE user SET name = ? WHERE id = ? RETURNING id, updated_at" , sql )
198+
199+ sql , _ = ub .BuildWithFlavor (SQLServer )
200+ a .Equal ("UPDATE user SET name = @p1 WHERE id = @p2" , sql )
201+
202+ sql , _ = ub .BuildWithFlavor (CQL )
203+ a .Equal ("UPDATE user SET name = ? WHERE id = ?" , sql )
204+
205+ sql , _ = ub .BuildWithFlavor (ClickHouse )
206+ a .Equal ("UPDATE user SET name = ? WHERE id = ?" , sql )
207+
208+ sql , _ = ub .BuildWithFlavor (Presto )
209+ a .Equal ("UPDATE user SET name = ? WHERE id = ?" , sql )
210+
211+ // Test with no returning columns
212+ ub2 := NewUpdateBuilder ()
213+ ub2 .Update ("user" )
214+ ub2 .Set (ub2 .Assign ("name" , "Test" ))
215+ ub2 .Where (ub2 .Equal ("id" , 1 ))
216+ ub2 .Returning () // Empty returning
217+
218+ sql , _ = ub2 .BuildWithFlavor (PostgreSQL )
219+ a .Equal ("UPDATE user SET name = $1 WHERE id = $2" , sql )
220+
221+ // Test with single column
222+ ub3 := NewUpdateBuilder ()
223+ ub3 .Update ("user" )
224+ ub3 .Set (ub3 .Assign ("name" , "Test" ))
225+ ub3 .Where (ub3 .Equal ("id" , 1 ))
226+ ub3 .Returning ("id" )
227+
228+ sql , _ = ub3 .BuildWithFlavor (PostgreSQL )
229+ a .Equal ("UPDATE user SET name = $1 WHERE id = $2 RETURNING id" , sql )
230+
231+ // Test with ORDER BY and LIMIT
232+ ub4 := NewUpdateBuilder ()
233+ ub4 .Update ("user" )
234+ ub4 .Set (ub4 .Assign ("name" , "Test" ))
235+ ub4 .Where (ub4 .Equal ("status" , 1 ))
236+ ub4 .OrderBy ("id" ).Asc ()
237+ ub4 .Limit (5 )
238+ ub4 .Returning ("id" , "name" )
239+
240+ sql , _ = ub4 .BuildWithFlavor (PostgreSQL )
241+ a .Equal ("UPDATE user SET name = $1 WHERE status = $2 ORDER BY id ASC LIMIT $3 RETURNING id, name" , sql )
242+
243+ // Test chaining
244+ ub5 := NewUpdateBuilder ().Update ("user" ).Set ("status = 1" ).Returning ("id" ).Returning ("name" , "updated_at" )
245+ sql , _ = ub5 .BuildWithFlavor (PostgreSQL )
246+ a .Equal ("UPDATE user SET status = 1 RETURNING name, updated_at" , sql ) // Last Returning call overwrites
247+
248+ // Test SQL injection after RETURNING
249+ ub6 := NewUpdateBuilder ()
250+ ub6 .Update ("user" )
251+ ub6 .Set (ub6 .Assign ("name" , "Test" ))
252+ ub6 .Where (ub6 .Equal ("id" , 1 ))
253+ ub6 .Returning ("id" , "name" )
254+ ub6 .SQL ("/* comment after returning */" )
255+
256+ sql , _ = ub6 .BuildWithFlavor (PostgreSQL )
257+ a .Equal ("UPDATE user SET name = $1 WHERE id = $2 RETURNING id, name /* comment after returning */" , sql )
258+
259+ // Test with CTE (WITH clause)
260+ cte := With (CTETable ("temp_user" ).As (Select ("id" ).From ("active_users" )))
261+ ub7 := cte .Update ("user" )
262+ ub7 .Set (ub7 .Assign ("status" , "active" ))
263+ ub7 .Where ("user.id IN (SELECT id FROM temp_user)" )
264+ ub7 .Returning ("id" , "status" )
265+
266+ sql , _ = ub7 .BuildWithFlavor (PostgreSQL )
267+ a .Equal ("WITH temp_user AS (SELECT id FROM active_users) UPDATE user SET status = $1 FROM temp_user WHERE user.id IN (SELECT id FROM temp_user) RETURNING id, status" , sql )
268+ }
0 commit comments