Add documentation and test example demonstrating how to use BuilderAs
to create nested JOIN queries. This is useful when joining with filtered
or transformed datasets.
fix#217
Implement new OrderByAsc(col) and OrderByDesc(col) methods for
SelectBuilder, UnionBuilder, UpdateBuilder, and DeleteBuilder. These
methods allow chaining multiple ORDER BY columns with different sort
directions, addressing the limitation where the old OrderBy/Asc/Desc
pattern could only apply a single direction to all columns.
Key changes:
- Add OrderByAsc(col string) and OrderByDesc(col string) to all four builders
- Each method appends the column with explicit ASC/DESC suffix
- Support chaining for complex ordering: OrderByDesc("score").OrderByAsc("name")
- Deprecate OrderBy/Asc/Desc methods with clear migration guidance
- Add comprehensive tests (TestSelectBuilder_OrderByAscDesc)
- Add example functions demonstrating usage
- Update all existing examples to use new API
- Update README.md with new "Build ORDER BY clause" section
This design is inspired by MyBatis-Plus and provides a more intuitive
and flexible API for handling multiple ORDER BY columns with different
sorting directions.
fix#214
Fixes#210
This commit adds the Returning method to both UpdateBuilder and DeleteBuilder,
following the same implementation pattern as InsertBuilder.
Changes:
- Add returning field to UpdateBuilder and DeleteBuilder structs
- Add updateMarkerAfterReturning and deleteMarkerAfterReturning markers
- Implement Returning methods for both builders
- Add RETURNING clause support for PostgreSQL and SQLite flavors
- Add comprehensive test coverage including:
- Basic functionality tests
- Flavor-specific behavior tests
- Edge cases (empty, single, multiple columns)
- Complex scenarios (ORDER BY, LIMIT, CTE)
- SQL injection compatibility
- Method chaining validation
The RETURNING clause is properly positioned after LIMIT and is ignored
for database flavors that don't support it (MySQL, SQL Server, CQL,
ClickHouse, Presto).
Example usage:
ub := Update("users").Set("name = ?", "John").Where("id = ?", 1).Returning("id", "updated_at")
db := DeleteFrom("users").Where("status = ?", "inactive").Returning("id", "deleted_at")
Queries that have both a limit and an offset build a query with a limit clause *before* the offset clause.
```go
fmt.Println(Select("*").From("table").Offset(5).Limit(10))
// SELECT * FROM table LIMIT 10 OFFSET 5
```
This seems to generate syntax errors in Trino. [Presto documentation specifies OFFSET before LIMIT](https://prestodb.io/docs/current/sql/select.html#limit-clause) in the SELECT statement documentation too, but is not very explicit about the reverse not being supported.
If the OFFSET and LIMIT clauses are swapped, the query succeeds.
Expected:
```go
fmt.Println(Select("*").From("table").Offset(5).Limit(10))
// SELECT * FROM table OFFSET 5 LIMIT 10
```