Skip to content

gdb: add RETURNING clause support for INSERT/UPDATE/DELETE operations #4552

@lingcoder

Description

@lingcoder

Is your feature request related to a problem?

Option Yes

Describe the solution you'd like

Add generic RETURNING clause support for INSERT/UPDATE/DELETE operations in gdb, allowing users to retrieve data from modified rows in a single database
round-trip.

Proposed API

// Basic RETURNING with specific fields
result, err := db.Model("users").Data(data).Returning("id", "created_at").Insert()

// RETURNING all fields
result, err := db.Model("users").Data(data).ReturningAll().Insert()

// Access returned records via type assertion
if rr, ok := result.(gdb.ReturningResult); ok {
records := rr.GetRecords()
// records contains the returned rows
}

// Convenience methods with automatic scanning
var user User
err := db.Model("users").Data(data).InsertAndScan(&user)

var users []User
err := db.Model("users").Data(data).Where("status", "active").UpdateAndScan(&users)

var deleted User
err := db.Model("users").Where("id", 1).DeleteAndScan(&deleted)

Database Support

Database Support Level
PostgreSQL Full support for INSERT/UPDATE/DELETE
SQLite Supported since version 3.35.0 (2021-03-12)
SQL Server Via OUTPUT clause
MariaDB Supported since 10.5.0
DaMeng Full support
MySQL Not supported (silently ignored)

Implementation Details

  1. New Interface: ReturningResult extending sql.Result with GetRecords() method
  2. Context Injection: Pass RETURNING fields via context to drivers
  3. Driver Support: Implement in pgsql, sqlite, dm drivers
  4. Convenience Methods: InsertAndScan, UpdateAndScan, DeleteAndScan

Describe alternatives you've considered

  1. Separate SELECT after INSERT: Requires two database round-trips and potential race conditions
  2. LastInsertId only: Limited to auto-increment IDs, doesn't support other generated columns (timestamps, UUIDs, etc.)
  3. Database triggers: Complex to maintain and not portable across databases

Additional

This feature is commonly needed when:

  • Getting auto-generated IDs after batch inserts
  • Retrieving database-generated timestamps (created_at, updated_at)
  • Capturing deleted records for audit logging
  • Getting computed column values after updates

Related implementations:

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions