@@ -227,3 +227,81 @@ func TestCompressionEnabledByDefault(t *testing.T) {
227227
228228 assert .Equal (t , "1" , value )
229229}
230+
231+ func TestUpdateReturningWithBindingsAlwaysReturnsRowset (t * testing.T ) {
232+ db , cleanup := setupDatabase (t )
233+ defer cleanup ()
234+
235+ const tableName = "test_update_returning_subquery_bindings"
236+
237+ if err := db .Execute (fmt .Sprintf ("DROP TABLE IF EXISTS %s" , tableName )); err != nil {
238+ t .Fatal (err .Error ())
239+ }
240+ defer func () {
241+ if err := db .Execute (fmt .Sprintf ("DROP TABLE IF EXISTS %s" , tableName )); err != nil {
242+ t .Fatalf ("DROP TABLE cleanup: %s" , err .Error ())
243+ }
244+ }()
245+
246+ if err := db .Execute (fmt .Sprintf ("CREATE TABLE %s (id INTEGER PRIMARY KEY, status TEXT, attempts INTEGER, payload TEXT)" , tableName )); err != nil {
247+ t .Fatal (err .Error ())
248+ }
249+
250+ if err := db .ExecuteArray (
251+ fmt .Sprintf ("INSERT INTO %s (id, status, attempts, payload) VALUES (?, ?, ?, ?), (?, ?, ?, ?)" , tableName ),
252+ []any {1 , "queued" , 0 , "first" , 2 , "done" , 3 , "second" },
253+ ); err != nil {
254+ t .Fatal (err .Error ())
255+ }
256+
257+ sql := fmt .Sprintf (`
258+ UPDATE %s
259+ SET status = ?, attempts = attempts + 1, payload = ?
260+ WHERE id = (
261+ SELECT id
262+ FROM %s
263+ WHERE status = ? AND attempts < ?
264+ ORDER BY id ASC
265+ LIMIT 1
266+ )
267+ RETURNING id, status, attempts, payload;
268+ ` , tableName , tableName )
269+
270+ result , err := db .SelectArray (
271+ sql ,
272+ []any {"running" , "picked" , "queued" , 5 },
273+ )
274+ if err != nil {
275+ t .Fatal (err .Error ())
276+ }
277+ defer result .Free ()
278+
279+ assert .True (t , result .IsRowSet ())
280+ assert .Equal (t , uint64 (4 ), result .GetNumberOfColumns ())
281+ assert .Equal (t , uint64 (1 ), result .GetNumberOfRows ())
282+ assert .Equal (t , "id" , result .GetName_ (0 ))
283+ assert .Equal (t , "status" , result .GetName_ (1 ))
284+ assert .Equal (t , "attempts" , result .GetName_ (2 ))
285+ assert .Equal (t , "payload" , result .GetName_ (3 ))
286+ assert .Equal (t , "1" , result .GetStringValue_ (0 , 0 ))
287+ assert .Equal (t , "running" , result .GetStringValue_ (0 , 1 ))
288+ assert .Equal (t , "1" , result .GetStringValue_ (0 , 2 ))
289+ assert .Equal (t , "picked" , result .GetStringValue_ (0 , 3 ))
290+
291+ emptyResult , err := db .SelectArray (
292+ sql ,
293+ []any {"running" , "picked-again" , "missing" , 5 },
294+ )
295+ if err != nil {
296+ t .Fatal (err .Error ())
297+ }
298+ defer emptyResult .Free ()
299+
300+ assert .True (t , emptyResult .IsRowSet ())
301+ assert .Equal (t , uint64 (4 ), emptyResult .GetNumberOfColumns ())
302+ assert .Equal (t , uint64 (0 ), emptyResult .GetNumberOfRows ())
303+ assert .Equal (t , "id" , emptyResult .GetName_ (0 ))
304+ assert .Equal (t , "status" , emptyResult .GetName_ (1 ))
305+ assert .Equal (t , "attempts" , emptyResult .GetName_ (2 ))
306+ assert .Equal (t , "payload" , emptyResult .GetName_ (3 ))
307+ }
0 commit comments