# Changelog

All notable changes to this project will be documented in this file.

The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## [v0.49.0] - 2026-07-20

- Fixed column_order on `*` selectors in sql queries in postgres

### Added

- Added `bob.NextUniqueInt()` for generating unique SQL alias suffixes ([#719](https://github.com/stephenafamo/bob/issues/719)). (thanks @atzedus)
- Code generation now emits a reflection-free `scan.Mapper` per table (`<table>ScanMapper`) that scans each result column directly into the struct field by index. The mapper is passed to the model constructor, so every query built from a model — `Query()`, relationship loaders, and `Insert`/`Update`/`Delete` with `RETURNING` — scans without the per-row reflection of `scan.StructMapper`. (thanks @sandonemaki)
- Generated `Where` structs now include relationship filters under an `R` field (e.g. `SelectWhere.Pilots.R.HasJets(filters ...bob.Mod[*dialect.SelectQuery])`) that filter rows by the existence of related rows, using a correlated `EXISTS` subquery (semi-join) built from the schema's relationship definitions. The `R` namespace mirrors the model struct and keeps the filters from colliding with column names. Unlike filtering through `SelectJoins`, this does not multiply parent rows, so `DISTINCT` is not needed and `Count()`/`LIMIT`-based pagination stay correct ([#722](https://github.com/stephenafamo/bob/pull/722)). (thanks @sandonemaki)

### Changed

- `NewViewx` and `NewTablex` in the `psql`, `mysql` and `sqlite` dialects now take a `scan.Mapper[T]` argument used for all queries built from the view/table. Pass `nil` to keep the previous reflection-based `scan.StructMapper` behaviour. `NewView`/`NewTable` are unchanged. (thanks @sandonemaki)
- JOIN a DISTINCT unnest(...) for composite-key relationship loaders & counts on PostgreSQL. (thanks @sandonemaki)

### Fixed

- Fixed an unused type import (e.g. `github.com/google/uuid`) in generated models when the type is only referenced through optional wrapper expressions, such as m2m relationship helpers for a join table with a `uuid` column ([#730](https://github.com/stephenafamo/bob/issues/730)).
- Fixed the counts plugin's generated `C` field reusing the `relation_tag` struct tag, which collided with the relations `R` field and caused `encoding/json` to drop both fields when a real tag name was configured. The `C` field now uses a dedicated `relation_tag_count` config option (default `"-"`). (thanks @jacobmolby)
- Fixed generated join alias suffixes using `randInt()`, which could produce negative values when `maphash.Hash.Sum64()` overflowed `int64` ([#719](https://github.com/stephenafamo/bob/issues/719)). Generated join mods now use `bob.NextUniqueInt()` instead. (thanks @atzedus)
- Fixed `orm.Query.Clone()` dropping the `Scanner`, which made `All`/`One`/`Cursor`/`Each` on a cloned query panic with a nil pointer dereference. (thanks @sandonemaki)

## [v0.48.0] - 2026-06-26

### Changed

- PostgreSQL single-column relationship loaders — both the slice relationship query (`<Parent>Slice.<Rel>`) and the batch count method (`<Parent>Slice.LoadCount<Rel>`) — now filter related rows with `col = ANY($1)` instead of `col IN (SELECT unnest($1))`, so the query planner can use an index scan on the foreign key instead of a `Seq Scan + Hash Semi Join`. Composite-key relationships keep the existing `IN (SELECT unnest(...))` form. (thanks @sandonemaki)

### Fixed

- Fixed PostgreSQL generated query parsing for CTEs that use table functions in `FROM` (for example `unnest(...) AS alias`), which could incorrectly widen CTE spans and generate malformed query mods such as duplicated outer `SELECT` projections.

## [v0.47.0] - 2026-06-22

### Added

- Added `column_order` config option (shared across all drivers). Set to `"name"` to sort generated model columns alphabetically, producing deterministic output regardless of the order migrations were applied to the database. Defaults to `"ordinal"` (previous behaviour: database physical column order). (thanks @cbarber)

### Changed

- Change the closure in `RunInTx` to pass `bob.Transaction` instead of `bob.Executor`

## [v0.46.0] - 2026-06-11

### Added

- `With()` on generated queries as a more ergonomic method to add mods on top of generated queries (thanks @daddz)
- Added `Asc()/Desc()/...` helpers to `sm.OrderCombined` for PostgreSQL/MySQL (thanks @daddz)
- Added SQLite `um.SetCols(columns...)` and `im.SetCols(columns...)` for tuple assignment in `UPDATE ... SET` and `ON CONFLICT DO UPDATE SET` (`.ToExprs(...)`, `.ToRow(...)`, `.ToQuery(...)`). SQLite renders `(cols) = (exprs...)`; PostgreSQL `ToRow` still emits `ROW (...)`. MySQL does not support tuple assignment — use multiple `SetCol` calls. (thanks @atzedus)

### Fixed

- Fixed generated `Setter.Apply` wrapping all insert values in a single `ExpressionFunc`, which prevented `BeforeInsertHooks` and query mods from modifying individual column values via `q.Values.Vals[row][columnIndex]`. Base and SQLite codegen templates now emit one expression per column (MySQL already did). Generated SQL is unchanged. (thanks @atzedus)
- Fixed generated query mods for combined `UNION/INTERSECT/EXCEPT` queries dropping or misrouting the first operand's `ORDER BY/LIMIT/OFFSET` into the combined-result clauses. (thanks @daddz)
- Fixed PostgreSQL `um` / `dm` standalone join mods (`InnerJoin`, `LeftJoin`, etc.) applied before `um.From(...)` / `dm.Using(...)`: the join is now preserved and attached to the next `FROM` / `USING` from_item instead of being dropped. (thanks @atzedus)
- Fixed/extended PostgreSQL `sm.From(...)`: it now accepts variadic join chains (`sm.From(table, joins...)`), and inline joins are merged with already attached standalone joins when replacing the primary `FROM` source. (thanks @atzedus)

### Changed

- Moved PostgreSQL `SetCols` tuple-assignment builder from `dialect/psql/dialect/setcols.go` to shared `clause/setcols.go` (`clause.NewSetCols`, `clause.SetColsOptions`). Dialect wrappers configure `ToRow` via `SetColsOptions.RowPrefix` (e.g. `"ROW"` on PostgreSQL). (thanks @atzedus)
- `EQ` comparisons passed to `SET` / `ON CONFLICT DO UPDATE SET` / `MERGE ... UPDATE SET` / MySQL `ON DUPLICATE KEY UPDATE` render without the extra parentheses used in `WHERE` / `ON` (e.g. `SET "users"."name" = $1` vs `WHERE ("users"."name" = $1)`). (thanks @atzedus)
- `NameAsExpr()` on dialect `View` / `Table` types (PostgreSQL, SQLite, MySQL) omits a redundant `AS` when the alias matches the table name (for example `FROM "users"` instead of `FROM "users" AS "users"`). An explicit alias is still emitted when a schema is set at construction (`AS "schema.table"`). (thanks @atzedus)
- Generated slice relationship loaders (`<Parent>Slice.Load<Relationship>`) now stitch loaded parents and children in O(N+M) using a map keyed by the join column, instead of the previous O(N×M) nested loop. This greatly speeds up eager-loading and then-loading relationships with many rows on both sides. The map is only used for single-column joins whose key type is comparable with `==`; composite keys and types with a custom `compare_expr` (e.g. `[]byte`) fall back to the original nested loop, so generated behaviour is unchanged. (thanks @sandonemaki)

## [v0.45.0] - 2026-05-28

### Added

- Added `Schema()` method to dialect `View` types (PostgreSQL, SQLite). (thanks @atzedus)
- Added `ColumnsExpr()` method on `psql.View` for parity with MySQL and SQLite views. (thanks @atzedus)
- Added `um.SetExpr` / `im.SetExpr` / `mm.SetExpr` for SET (and PostgreSQL/SQLite `im.SetExpr` for `ON CONFLICT DO UPDATE SET`) when the assignment LHS is a qualified or arbitrary expression — pass `dialect.Quote(...)` or another `bob.Expression`. `SetCol` / `UpdateCol` remain for a single column name (quoted automatically). (thanks @atzedus)

### Changed

- **BREAKING:** `psql.F` / `mysql.F` / `sqlite.F` and `dialect.NewFunction` now take `name any` (was `string`). The name is rendered with `bob.Express`; use a string for a literal function name or `dialect.Quote("schema", "fn")` for qualified names. (thanks @atzedus)
- **BREAKING:** `mods.Set` is now a struct with a `Col any` field instead of a `[]string` alias. `um.SetCol` / `im.SetCol` / `mm.SetCol` (and MySQL `im.UpdateCol`) take a `string` column name and quote it automatically; use `SetExpr` for qualified or arbitrary LHS expressions. `SetCol(...).To(...)` / `SetExpr(...).To(...)` implement `bob.Expression` and can be passed to `um.Set` / `im.Set` / `mm.Set` to group several assignments in one mod (they still work as standalone query mods). (thanks @atzedus)
- Godoc on `sm.With`, `sm.Window`, `wm.BasedOn` (PostgreSQL, MySQL, SQLite) notes that CTE/window names are quoted as SQL identifiers. (thanks @atzedus)
- **BREAKING:** PostgreSQL `sm.ForUpdate`, `sm.ForNoKeyUpdate`, `sm.ForShare`, and `sm.ForKeyShare` now take `tables ...any` instead of `tables ...string`. Pass `psql.Quote(...)` (or another `Expression`) for each locked relation ([#693](https://github.com/stephenafamo/bob/issues/693)). (thanks @atzedus)
- **BREAKING:** MySQL `sm.ForUpdate` and `sm.ForShare` now take `tables ...any` with the same semantics as PostgreSQL (`mysql.Quote(...)` when needed). (thanks @atzedus)
- **BREAKING:** `clause.Lock.Tables` is now `[]any` instead of `[]string` (used by `FOR UPDATE` / `FOR SHARE` rendering). (thanks @atzedus)
- **BREAKING:** `View` / `Table` `Name()` now returns the bare table (or view) name as `string`. In v0.44.0, `Name()` returned a dialect `Expression` (qualified table reference for SQL). That role moved to new methods:
  - `NameExpr()` — what `Name()` did in v0.44.0 (on PostgreSQL and SQLite, respects `UseSchema` when schema was generated empty)
  - `NameAsExpr()` — what `NameAs()` did in v0.44.0 (name plus table alias)
    Update manual call sites, codegen templates, and generated models: `Users.Name()` in SQL builders → `Users.NameExpr()`, `Users.NameAs()` → `Users.NameAsExpr()`; use `Users.Name()` when you need the unqualified name string. On PostgreSQL and SQLite, `Schema()` still returns the schema when set.
- Codegen templates and `orm.Preload` now use `NameExpr()` / `NameAsExpr()` instead of `Name()` / `NameAs()`. (thanks @atzedus)

### Fixed

- Fixed SQL identifier quoting in shared clause builders (CTE names/columns, window names, `ON CONFLICT ON CONSTRAINT`, `WHERE CURRENT OF`, partition/index lists, SQLite `INDEXED BY`) and PostgreSQL `MERGE`/`SetCols` column lists, table-function column definitions, and MySQL optimizer-hint table lists. Simple identifier parameters are quoted automatically; pass `dialect.Quote(...)` for qualified names in `any` slots (`From`, `OnConflict`, `FOR UPDATE OF`, etc.). (thanks @atzedus)
- Fixed PostgreSQL `sm.From` clearing joins already on the `FROM` from_item (e.g. `sm.CrossJoin` before `sm.From`) because `SelectQuery.AppendTableRef` replaced the entire embedded `FROM` table ref. Existing joins are merged into the new primary table ref. (thanks @atzedus)
- Fixed `FOR UPDATE` / `FOR SHARE` `OF` table lists: pass `psql.Quote(...)` / `mysql.Quote(...)` so names with spaces or qualification render correctly ([#693](https://github.com/stephenafamo/bob/issues/693)). (thanks @atzedus)
- Fixed MySQL `sm.From(...).UseIndex` / `ForceIndex` / `IgnoreIndex` (and `*ForJoin` / `*ForOrderBy` / `*ForGroupBy` variants) not appearing in generated SQL because `FromChain.Apply` did not copy `IndexHints` onto the query. (thanks @atzedus)
- Fixed generated models using the wrong column qualifier when a table was constructed with a non-empty schema. Codegen previously passed `table.Key` into `build*Columns` and `pkEQ` / `pkIN`, but dialect `View` / `Table` types use `schema.table` as `Alias()` whenever `schema` is set at construction. That mismatch produced SQL such as `` `users`.`id` `` in `WHERE` while `FROM` used `` `myapp`.`users` AS `myapp.users` `` (columns and primary-key expressions did not match the table alias from `NameAsExpr()`). Templates now use a `tableColumnAlias` helper: `schema.name` when `schema` is set, otherwise `table.Key`. (thanks @atzedus)
- Fix issue with overwriting unique constraints for tables beloging to other schemas. (thanks @eaglehuntt and @MD-Mushfiqur123)

## [v0.44.0] - 2026-05-21

### Added

- Added PostgreSQL `MERGE` statement SQL parser used for sql-to-code generation (thanks @atzedus)
- Added `R.Loaded` to generated models, a nested struct with one `bool` per relationship that records whether each relationship has been loaded. This disambiguates "not loaded yet" from "loaded, but no related rows" for both to-one and to-many relations. Maintained automatically by `Load*`, `Preload`, `ThenLoad`, factory builds, and to-one `Attach`/`Insert` ops. The `Loaded` alias can be changed in the bob config. (thanks @jacobmolby)
- Added `As(alias)` method to `bob.BaseQuery`, allowing queries (e.g. `mysql.Select(...)`) to be aliased directly when used as subqueries in a column list. (thanks @jacobmolby)
- Added columns API: generated column structures now provide `Name() string` method. (thanks @atzedus)
- Added `expr.ColumnsExpr` accessor methods: `Parent() []string`, `AggFunc() [2]string`, `AliasPrefix() string`, and `AliasDisabled() bool`. `WithParent(...)` now filters empty parts, and default rendering for plain unqualified columns no longer emits redundant self-aliases (e.g. `"name"` instead of `"name" AS "name"`). (thanks @atzedus)
- Added `bob.ParensOmitter` interface with `ShouldOmitParens() bool` to let expressions opt out of automatic parenthesis wrapping in expression builders. (thanks @atzedus)
- Added PostgreSQL `RETURNING WITH (OLD AS ..., NEW AS ...)` support for `INSERT`, `UPDATE`, `DELETE`, and `MERGE` query builders, including fluent modifiers: `im/um/dm/mm.Returning(...).WithOldAs(...).WithNewAs(...)`. (thanks @atzedus)
  - Note: `bobgen-psql` sql-to-code parsing for this syntax is currently blocked by upstream PostgreSQL parser dependency support.
- Added PostgreSQL `TABLESAMPLE ... REPEATABLE ...` support via fluent modifiers on `sm.From(...)` and join chains. (thanks @atzedus)
- Added PostgreSQL `JOIN ... USING (...) AS alias` support via `UsingAs(alias, cols...)` on psql join chains. (thanks @atzedus)
- Added PostgreSQL GROUP BY grouping-element helpers: `sm.Grouping(...)`, `sm.Rollup(...)`, `sm.Cube(...)`, and `sm.GroupingSets(...)`. (thanks @atzedus)
- Added PostgreSQL `im.ConflictTarget(...)` helper for composing `ON CONFLICT` target items with optional `.Collate(...)` and `.OpClass(...)` modifiers. (thanks @atzedus)
- Added PostgreSQL UPDATE/MERGE tuple-assignment helper `um.SetCols(columns...)` with `.ToExprs(...)`, `.ToRow(...)`, and `.ToQuery(...)` support. (thanks @atzedus)
- Added PostgreSQL UPDATE/DELETE `um.WhereCurrentOf(cursor)` modifier to render `WHERE CURRENT OF <cursor>`. (thanks @atzedus)
- Added `expr.NoSep` sentinel to join expressions without any separator. The existing `expr.Join` default (space) is unchanged. (thanks @atzedus)
- Added `im.Excluded(column)` helper (PostgreSQL and SQLite) for `ON CONFLICT DO UPDATE` assignments — renders as `EXCLUDED."col"` with no extra space, reused internally by `im.SetExcluded(...)` and available for direct use in `im.SetCol(...).To(...)`. (thanks @atzedus)
- Added PostgreSQL `psql.TableFunctions(funcs)` and `sm.FromFunction` / `um.FromFunction` / `dm.UsingFunction` helpers that return `bob.Expression` for table-function `from_item` sources (`ROWS FROM (...)` when multiple functions are given). (thanks @atzedus)
- Added PostgreSQL `um.From(table, joins...)` and `dm.Using(table, joins...)` variadic join arguments so each appended `from_item` can include inline `INNER JOIN`, `LEFT JOIN`, `CROSS JOIN`, etc. (`JoinChain` builders). (thanks @atzedus)
- Added `bobgen-psql` support for multiple `UPDATE ... FROM` / `DELETE ... USING` sources: sql-to-code emits `AppendTableRef(...)` per parsed `from_item` and resolves column sources from every item. (thanks @atzedus)

### Changed

- **BREAKING:** Renamed the generated `ThenLoadCount` variable to `SelectThenLoadCount` for naming consistency with `SelectThenLoad`/`InsertThenLoad`/`UpdateThenLoad`. Update call sites from `models.ThenLoadCount.X.Y` to `models.SelectThenLoadCount.X.Y`. (thanks @jacobmolby)
- **BREAKING:** `mm.SetCol()` now returns `mods.Set[*mm.UpdateAction]` instead of a custom `SetChain` type. `.ToExpr(val)` is replaced by `.To(val)`, and `.ToDefault()` is replaced by `.To(psql.Raw("DEFAULT"))`. `.To()` and `.ToArg()` work as before. (thanks @atzedus)
- **BREAKING:** `mm.Recursive()` has been removed. PostgreSQL does not support `WITH RECURSIVE` in MERGE statements. (thanks @atzedus)
- **BREAKING:** Generated `*Columns` accessor fields now return a dialect-specific wrapper type (e.g., `userColumn`) instead of plain `dialect.Expression`. The wrapper still implements `dialect.Expression` and avoids extra auto-parentheses in expression builders. Use `.Expression` only when you explicitly need the embedded expression value. (thanks @atzedus)
- **BREAKING:** PostgreSQL `UPDATE ... FROM` and `DELETE ... USING` additional sources now live in `UpdateQuery.FromItems` / `DeleteQuery.UsingItems` instead of the embedded `clause.TableRef` on the query struct. Each `um.From(...)` or `dm.Using(...)` appends one comma-separated `from_item` (last call no longer wins). Use `um.Table(...)` / `dm.From(...)` for the update/delete target table. (thanks @atzedus)
- **BREAKING:** PostgreSQL `sm.FromFunction` and `um.FromFunction` no longer return `FromChain` or apply `FROM`/`USING` by themselves. They return `bob.Expression` and must be passed to `sm.From(...)` / `um.From(...)` / `dm.Using(...)` — e.g. `sm.From(sm.FromFunction(psql.F("generate_series", 1, 3)()))` instead of `sm.FromFunction(...)`. Aliasing and other table modifiers belong on `sm.From(...)` / `um.From(...)`. (thanks @atzedus)
- **BREAKING:** PostgreSQL `sm.From` / `FromChain` for `SelectQuery` now set the `FROM` source via `AppendTableRef` (replace semantics) instead of `SetTable` / `SetTableAlias` on a `fromable` interface. (thanks @atzedus)
- **BREAKING:** PostgreSQL `um` / `dm` join helpers (`InnerJoin`, `LeftJoin`, `CrossJoin`, etc.) return `JoinChain[*UpdateQuery]` / `JoinChain[*DeleteQuery]`. Use them in `um.From(table, joins...)` / `dm.Using(table, joins...)`, or as standalone mods after `um.From` / `dm.Using` — `AppendJoin` then attaches to the last `FromItems` / `UsingItems` entry. (thanks @atzedus)
- **BREAKING:** PostgreSQL psql join chain modifiers `.Natural()`, `.On()`, `.OnEQ()`, `.Using()`, and `.UsingAs()` now return `JoinChain` for fluent chaining instead of `bob.Mod`. (thanks @atzedus)

### Fixed

- Fix PostgreSQL `sm.From` replacing a previous `FROM` without clearing a stale table alias when the new source has no alias. (thanks @atzedus)
- Fix PostgreSQL `sm.With(...).SearchBreadth(...)` rendering `SEARCH DEPTH` instead of `SEARCH BREADTH` in CTE queries. (thanks @atzedus)
- Avoid unnecessary imports in generated random factory code when a type has no random expression. (thanks @jay-babu)
- Fix missing base type imports (e.g. `github.com/google/uuid`) in generated models when using `type_system: "database/sql"` and `uuid_pkg: google`, which could cause compile errors in generated many-to-many relation helpers. (thanks @atzedus)
- Reuse parents when creating children in factory (thanks @abdusco)

## [v0.43.0] - 2026-04-29

### Added

- Added PostgreSQL `MERGE` statement support with full syntax including:
  - `MERGE INTO ... USING ... ON ...` with table aliases and `ONLY` modifier
  - `WHEN MATCHED`, `WHEN NOT MATCHED`, `WHEN NOT MATCHED BY SOURCE` clauses
  - `UPDATE`, `INSERT`, `DELETE`, `DO NOTHING` actions
  - Support for `AND condition` in WHEN clauses
  - `OVERRIDING SYSTEM VALUE` and `OVERRIDING USER VALUE` for INSERT actions
  - `RETURNING` clause support (PostgreSQL 17+) (thanks @atzedus)
  - Note: the SQL parser used for sql-to-code generation does not yet support `MERGE` statements
- Added `psql.SetVersion`, `psql.GetVersion`, and `psql.VersionAtLeast` functions for context-based PostgreSQL version management (thanks @atzedus)
- Added `Table.Merge()` method for ORM-style MERGE operations with automatic `RETURNING *` for PostgreSQL 17+ (thanks @atzedus)
- Added `mm` package with modifiers for building MERGE queries (`mm.Into`, `mm.Using`, `mm.WhenMatched`, `mm.WhenNotMatched`, `mm.WhenNotMatchedBySource`, etc.) (thanks @atzedus)
- Added `enum_format` configuration option to control enum value identifier formatting. Options: `"title_case"` (default, e.g., `InProgress`) or `"screaming_snake_case"` (e.g., `IN_PROGRESS`).
- Added `Unqualified()` method to generated column structures that returns columns without table alias/prefix. (thanks @atzedus)
- Added `PreloadCount` and `ThenLoadCount` to generate code for preloading and then loading counts for relationships. (thanks @jacobmolby)
- MySQL support for insert queries executing loaders (e.g., `InsertThenLoad`, `InsertThenLoadCount`). (thanks @jacobmolby)
- Added overwritable hooks that are run before the exec or scanning test of generated queries. This allows seeding data before the test runs.
- Added `bob.Each` function to iterate over query results (range-over-func). (thanks @toqueteos)
- Added support for the `VALUES` statement in MySQL, PostgreSQL, and SQLite. (thanks @manhrev)
- Added MariaDB compatibility check in gen/bobgen-mysql (thanks @dumdev25)
- Added `ALL`, `SOME`, `ANY` expressions for MySQL and PostgreSQL dialects. Added `EXISTS` expression for all dialects. (thanks @manhrev)
- Added a customizable MySQL and PostgreSQL driver image setting for `bobgen-sql`. (thanks @manhrev)
- Added support for Materialized Views in PostgreSQL code generation. (thanks @PudottaPommin)

### Fixed

- Fix `pgx` driver `Commit()` returning `nil` instead of `pgx.ErrTxClosed` when the transaction is already closed (e.g., rolled back by context expiry). This prevented silent data loss by correctly propagating the error to the caller. (thanks @wucm667)
- Fix factory `FromExisting` methods causing stack overflow when models have bidirectional relationships populated (thanks @wucm667)
- Fix self-referencing relationship back-references so generated preload/load helpers no longer create cyclic parent links. (thanks @atzedus)
- Fix collisions for preloader alias generation. Replaced `RandInt` with `NextUniqueInt` (thanks @atzedus)
- Fix an issue where the random function of aliased custom types were not being used in generated query tests.
- Properly recognize placeholders in LIMIT and OFFSET when generating queries for PostgreSQL.
- Throw an error on an empty SET clause during SQL generation rather than sending invalid syntax to database. (thanks @Xaeroxe)
- Fix MySQL `Insert().One()`/`All()`/`Cursor()` using `SELECT *` instead of explicit model columns when re-fetching inserted rows, consistent with PostgreSQL/SQLite `RETURNING`. (thanks @tak848)

## [v0.42.0] - 2025-11-25

### Fixed

- Fixed a bug where the generated loaders for many-to-many relationships were skipping related rows. (thanks @TylerJGabb)

### Added

- Include `shell.nix` for developers using [Nix](https://nixos.org/) to create development environments. (thanks @EliRibble)
- Additional README content on how developers can use linting and unit testing to contribute. (thanks @EliRibble)
- Added `Plus` expression chain method (thanks @atzedus).

### Changed

- Export `orm.NullTypeConverter`. (thanks @Serjlee)
- Uses `io.StringWriter` instead of `io.Writer` for efficiency since we are always writing strings.

## [v0.41.1] - 2025-09-02

### Fixed

- Properly handle code generation tests for compound queries in MySQL.

## [v0.41.0] - 2025-09-02

### Added

- `drivers/pgx.Pool` now includes the methods `Acquire` and `AcquireFunc` which mirror the methods in `pgx/v5/pgxpool` to acquire a connection from the pool (thanks @Eyal-Shalev).
- Added the `drivers/pgx.PoolConn` type which is a wrapper around `pgx/v5/pgxpool.Conn`.

### Changed

- Use the full column type and not just the datatype as the `DBType` in bobgen-mysql.
- `bob.Transactor` is now a generic interface so that implementations can use a concrete transaction type.
- The data types generated for SQLite now follow SQLite's type affinity rules more closely (excluding some common names). As a result, all integer types are now mapped to `int64` and all floating point types are mapped to `float64`.

### Fixed

- Fixed an issue where `bobgen-mysql` could not detect unsigned integer columns in queries.
- Properly close `pgx` transactions if the context used in `BeginTx` is cancelled.
- Fix issues with generating code for relationships defined with `WhereExpr`.
- Support `uint64` type when scanning columns as `types.Uint64`. This fixes scanning `BIGINT UNSIGNED` MySQL columns as `types.Uint64` when `interpolateParams` is enabled. (thanks @luiscleto)
- Properly handle code generation tests for compound queries in MySQL.
- Fix an issue where some ids are uppercased by the MySQL query code generator.

## [v0.40.2] - 2025-08-16

### Fixed

- Fixed Scanner/Valuer test gen for types defined in the models package.
- Fix issue with randomization test when enum is only used in an array.
- Fix issue with using `CompareExpr` with values that are null.
- Fix issue with imports in query tests.
- Fix issue with detecting the columns in a CTE in `bobgen-psql`.
- Properly detect the end of a function call in postgres qury parser.

## [v0.40.1] - 2025-08-14

### Fixed

- Fixed bug in preloading

## [v0.40.0] - 2025-08-13

### Added

- Made code generation modular by relying on built-in plugins that can be enabled or disabled in the configuration.
  - `dbinfo`: Generates code for information about each database. Schemas, tables, columns, indexes, primary keys, foreign keys, unique constraints, and check constraints.
  - `enums`: Generates code for enums in a separate package, if there are any present.
  - `models`: Generates code for models. Depends on `enums`.
  - `factory`: Generates code for factories. Depends on `models`.
  - `dberrors`: Generates code for unique constraint errors. Depends on `models`.
  - `where`: Generates type-safe code for `WHERE` clauses in queries. Depends on `models`.
  - `loaders`: Adds templates to the `models` package to generate code for loaders e.g `models.SelectThenLoad.Table.Rel()`.
  - `joins`: Adds templates to the `models` package to generate code for joins e.g `models.SelectJoin.Table.LeftJoin.Rel`.
  - `queries`: Generates code for queries.
- Added new `types.Uint64` type that sends values to the database as strings. This is necessary because using `uint64` directly can cause an overflow if the value exceeds the maximum value of an `int64`. This is a limitation imposed by `database/sql/driver.Valuer` interface.
- Added support for `pgvector` types during code generation.
  - `pgvector.Vector`
  - `pgvector.HalfVector`
  - `pgvector.SparseVector`

### Changed

- Enums are now imported directly from a new generated `enums` package. This makes it easier to use enums in other packages without having to depend on the `models` package.
- Preload functions now take a custom `orm.PreloadRel` struct instead of reusing `orm.Relationship`.
- By default, factories are now generated in `./factory` instead of `./models/factory`.
- Outputs are now determined by plugins which can be enabled or disabled in the configuration.
- UniqueConstraintErrors are now generated in a separate `dberrors` package instead of being generated in the `models` package.
- Tests in the generated `models` package are no longer generated in a separate `models_test` package. There is no longer any circular dependency since tests for the unique constraint errors are generated in the `dberrors` package.
- `orm.Columns` has been moved to `expr.ColumnsExpr`.
- `orm.NewColumns` has been moved to `expr.NewColumnsExpr`.
- `<Table>.Columns()` is removed. The columns expression is now expected to be embedded in the `Columns` field of the `<Table>` struct.
- `<dialect>.View` and `<dialect>.Table` now take an additional type parameter for the columns type. This is assigned to the `Columns` field with `NewView/NewTable` functions.

### Removed

- Removed the `no_factory` configuration option. It is now replaced with the `factory` plugin which can be enabled or disabled. See <https://bob.stephenafamo.com/docs/code-generation/configuration#plugins-configuration> for more details.
- Removed the `Only` and `Except` exported functions in `orm`. They are now in the private `internal` package.
- Removed the generated `models.<Model>Columns` global variable. It can now be accessed through `models.<Table>.Columns`.
- Removed the generated `models.TableNames` and `models.ColumnNames` global variables. Their use can be replaced with the `dbinfo` plugin which generates a `dbinfo` package with all the information about the database.

### Fixed

- Fixed issue with redundant title casing column names in query templates. (thanks @luiscleto)
- Fix invalid expression with pointer-based type systems. (thanks @tak848)
- Fix panic when parsing SQLite `UPDATE` queries that do not contain a `FROM` clause.
- Fix issue when using enums in generated queries.
- Fix randomization of floats and decimals in the factory.
- Fix JSON data being incorrectly hex-encoded as bytea when using pgx through simple protocol, causing PostgreSQL to reject it with invalid input syntax errors. (by @Maxitosh)
- Fix issue with preload queries not using a defined schema on the related tables

## [v0.39.0] - 2025-07-28

### Added

- Added the `As` method to `clause.TableRef`, which sets the alias and return a copy of the struct. (thanks @Nitjsefni7)
- Added the `type_system` configuration option to determine how to generate null and optional values in the generated code.
  Possible options: `github.com/aarondl/opt`, `github.com/aarondl/opt/null` or `database/sql`. The default value is `github.com/aarondl/opt`.
- When generating code for queries, The `All` method of the generated query will return a struct with nested fields instead of a flat struct.
  - columns with dots (`.`) are assumed to be a `to-many` nested field.
  - columns with double underscores (`__`) are assumed to be a `to-one` nested field.
- Implement `--prefix` annotation in queries for `bobgen-psql`.
- Add FromExisting**Rel** method to factories to create a template from an existing model. (thanks @dutow)
- Add WithExisting**Rel** to factory mods to attach an existing model as a relationship. (thanks @dutow)
- Added support in psql for combined args (order by, limit etc.) in combined queries and use parens if they are present. (@iwyrkore)
- Added parens for combined queries. (@iwyrkore)
- Match columns using regular expressions in type replacements. This is useful for e.g. matching columns that have a common prefix or suffix. (thanks @abdusco)

### Changed

- `Mod` is now a separate field in `orm.ModQuery` and `orm.ModExecQuery`.
- `Allx` now takes a `Transformer` type parameter to transform the result of the query.
- Updated documentation for readability, added code gen examples. (thanks @singhsays)
- Columns are now matched in a case-insensitive manner in type replacements. (thanks @abdusco)
- Columns can now be matched with as many conditions as needed in type replacements. This removes the previous requirement that boolean fields had to be specified in addition to a string field. (thanks @abdusco)
- Factories now expose a `NewXWithContext` that accepts a context in addition to `NewX` that does not. This provides a cleaner API for the callers, while still allowing the use of context internally. (thanks @abdusco)

### Removed

- Removed the `fallback_null` configuration option. It is now replaced with the `type_system` configuration option.

### Fixed

- Fixed some issues with creating relationships in the factory by avoiding trying to reuse models.
- Fix issues with generating code for queries with duplicate return column names.
- Updated gen table detail queries to use context. (thanks @singhsays)
- Properly detect `bool`, `timestamp` and `timestamptz` types in `bobgen-psql`.
- Fix transformer for single result queries.
- Properly handle indexes where the sorting order can be null.
- Check for nullability when loading relationships.
- Handle table names quoted with backticks in mysql query parser. (thanks @luiscleto)
- Allow matching columns in type replacements by the `autoincr` property as stated in the docs. (thanks @abdusco)
- Handle dashes and spaces in generated enum values properly (thanks @abdusco)
- Check for nullability when loading relationships from Slices (thanks @felipeparaujo)

## [v0.38.0] - 2025-06-04

### Added

- Added the `fallback_null` top level configuraiton option. Which can be either `database/sql` or `github.com/aarondl/opt/null`.  
   This is used to determine how to create null values in the generated code. If set to `database/sql`, it will use `sql.Null[T]` for nullable types, and if set to `github.com/aarondl/opt/null`, it will use `opt.null.Val[T]`.  
   The default value is `database/sql`.

### Fixed

- Correctly build models with nested relationships in the factory.
- Fix a performance issue with code generation in `bobgen-psql`.
- Use the correct alias when generating table columns.
- Fix issue with generating factory code for tables with schema names.

## [v0.37.0] - 2025-05-31

### Added

- Added the `drivers/pgx` package which contains types and functions to use a `pgx/v5` connection as a `bob.Executor`.
- Added support for `github.com/ncruces/go-sqlite3`. (thanks @ncruces)
- Added support for configuring what type to generate specific null versions of a type instead of always wrapping with `sql.Null[T]`.

### Changed

- The `bob.Transaction` interface now takes a `context.Context` argument in the `Commit` and `Rollback` methods.
- The method `BeginTx` on the `bob.Transaction` interface is now changed to `Begin` and it takes a single context argument.  
   This is to make it easier to implement for non `database/sql` drivers.
- In the generated model, the `PrimaryKeyVals()` method is now private.
- Renamed `driver_name` to `driver` in code generation configuration.
- In type replacements, nullability is not used in matching.
  Previously, nullability of matches was set to false by default, and would require an additional replacement to also match nullable columns.

### Removed

- Removed the `New` and `NewQueryer` functions. Any of `bob.NewDB`, `bob.NewTx` or `bob.NewConn` can be used instead.
- Removed the `StdInterface` interface as it is unnecessary.
- Remove redundant `orm.Model` interface.
- Remove dependence on `github.com/aarondl/opt` in generated code.
  - Nullable values are now wrapped `database/sql.Null` with instead of `github.com/aarondl/opt/null.Val`.
  - Optional values are now represented as pointers instead of `github.com/aarondl/opt/omit.Val[T]`.
- Removed `in_generated_package` type configuration option. This was limited and could only indicate that the type is in the models package.
  Instead the full import path can now be used in the `imports` configuration option, and if it is in the same package as the generated code, the prefix will be automatically removed.

### Fixed

- Properly handle `nil` args when checking if default or null in `mysql` table insert query.
- Fix bug in querying slice relationships in MySQL and SQLite.

## [v0.36.1] - 2025-05-27

### Fixed

- Fixed issue with generating correct test code for nullable args in SQL queries.
- Fix issue where writing the "NO EDIT Disclaimer" at the top of Go generated files was skipped.

## [v0.36.0] - 2025-05-27

### Changed

- Loaders are now generated as singular instead of plural. This feels more natural when using them in code.

  ```go
  // Before
  models.Preload.Users.Pilots()
  models.SelectThenLoad.Users.Pilots()

  // After
  models.Preload.User.Pilots()
  models.SelectThenLoad.User.Pilot()
  ```

## [v0.35.1] - 2025-05-27

### Fixed

- Store `types.Time` as an RFC3339 string in the DB

## [v0.35.0] - 2025-05-26

### Added

- Added support to generate code for `SELECT`, `INSERT`, `UPDATE` and `DELETE` queries in `bobgen-mysql`.
- Added support to generate code for `INSERT`, `UPDATE` and `DELETE` queries in `bobgen-sqlite`.
- Added `LIMIT` and `OFFSET` to the SQLite Update and Delete queries.
- Added `IndexedBy` and `NotIndexed` mods to the SQLite Delete queries.
- Added the `Transactor` and `Transaction` interfaces.
- Added the `SeparatePackageForTests` attribute to generation outputs to indicate if generated tests should have their own package.
- Added the `RandomColumnNotNull` mod to factories to generate random values for non-nullable columns without the chance of being null.
- Added the `WithOneRelations` mod to factories to include every relation for a factory template.
- Added `clause.TableRef` which merges `clause.Table` and `clause.From` since they had overlapping functionality.
- Added `RunInTx` method to `bob.DB`. This starts a transaction and calls the given function with this transaction.
- Add support for MySQL to `bobgen-sql`.
- Added `Exec` test for generated queries that do not return rows.
- Added `OrderCombined`, `LimitCombined`, `OffsetCombined` mods to MySQL `SELECT` queries. These are applied to the result of a `UNION`, `INTERSECT` or `EXCEPT` query.
- Added `type_limits` property to column definitions.
- Added `limits` option to `random_expr` function for types. This is to pass any column limits to the randomization function (e.g. `max_length` for strings).
- Added tests to check that the generated factory can create models and save into the database.
- Added the `pgtypes.Snapshot` type for the `pg_snapshot` and `txid_snapshot` type in PostgreSQL.
- Added a custom `Time` type to the `types` package. This is motivated by the fact that the `libsql` driver does not support the `time.Time` type properly.
- Added an option to disable aliasing when expressing `expr.Columns`. Also added `EnableAlias` and `DisableAlias` methods to `expr.Columns` to control this behavior.
- Added a `PrimaryKey` method to `{dialect}.Table` to get the primary key columns of the table.

### Changed

- Changed the INDEXED BY and NOT INDEXED mods for SQLite update queries from `TableIndexedBy` and `TableNotIndexed` to `IndexedBy` and `NotIndexed`.
- Use `LIBSQL_TEST_SERVER` environment variable to run tests against a libSQL server instead of the hardcoded `localhost:8080`.
- `BeginTx` now returns a `Transaction` interface instead of a `bob.Tx`.
- Generated tests that required a database connection no longer create a new connection for each test. Instead it depends on a `testDB` connection that the user has to provide.
- In the generated models, relationships for `ModelSlice` are now loaded using arrays to reduce the number of parameter in the query.

  ```sql
  -- Before
  SELECT * FROM pilots WHERE jet_id IN ($1, $2, $3, ...); -- Parameters increase with the number of pilots

  -- After
  SELECT * FROM pilots WHERE jet_id IN (SELECT unnest(CAST($1 AS integer[])); -- Parameters are always 1
  ```

- In the generated model code, `Preload` is now a struct instead of multiple standaalone functions.  
   It is now used like `Preload.User.Pilots()`, instead of `PreloadUserPilots()`.
- In the generated model code, `ThenLoad` is now a struct and has been split for each query type.  
   It is now used like `SelectThenLoad.User.Pilots()`, instead of `ThenLoadUserPilots()`.
- In the generated model code, the **Load** interfaces no longer include the name of the source model since it is a method on the model.  
   It now looks like `*models.User.LoadPilots` instead of `*models.User.LoadUserPilots`.
- Made changes to better support generating code in multiple languages.
- Mark queries with `ON DUPLICATE KEY UPDATE` as unretrievable in MySQL.
- Unretrievable `INSERT` queries using `One, All, Cursor` now immediately return `orm.ErrCannotRetrieveRow` instead of executing the query first.
- Generated tests are now run when testing drivers.
- `MEDIUMINT` and `MEDIUMINT UNSIGNED` are now generated as `int16` and `uint16` respectively. This is because Go doe not support 24 bit integers.
- The randomization function for floats, strings, and decimals now respect the limits set in the column definition.
- `txid_snapshot` is now generated as `pgtypes.Snapshot` instead of `pgtypes.TxIDSnapshot`.
- `cidr` postgres type is now generated as `types.Text[netip.Prefix]` instead of `types.Text[netip.Addr]`.
- `money` postgres type is now generated as a string with a custom randomization expression instead of a decimal.
- Factory template mods now take a context argument. This allows for more control when using recursive mods.
- Removed `WithOneRelations` mod from factories, now replaced with `WithParentsCascading` which also includes parents for any parent relationships.

### Removed

- Removed `clause.Table` and `clause.From`, and merge into `clause.TableRef` since they had overlapping functionality.
- Remove unnecessary context closure in generated join helpers.
- Remove the deprecated `wipe` generation option.
- Remove `pgtypes.TxIDSnapshot` type. This is now replaced with `pgtypes.Snapshot`.

### Fixed

- Use correct row name for generated queries in `bobgen-sqlite`.
- Properly select query comment in `bobgen-sqlite`.
- Fixed issue with using generated queries with `VALUES` as mods.
- Moved `Partitions` in MySQL delete queries to after the table alias.
- Fixed issue with inserting into a table with all rows having default values in SQLite.
- Use table name and not table alias in SQLite returning clause since the alias is not available in the `RETURNING` clause.
- Fixed generated unique constraint errors for SQLite.
- Correctly resuse inserted rows in factories.

## [v0.34.2] - 2025-05-01

### Fixed

- Fix bug with `bobgen-psql` parsing of string identifiers in certain cases.

## [v0.34.1] - 2025-04-30

### Fixed

- Remove unnecessary limitation to place `FETCH WITH TIES` before `OFFSET`.
- Fix issue with verifying statements in `bobgen-psql`.

## [v0.34.0] - 2025-04-30

### Added

- Added support to generate code for `UPDATE`, and `DELETE` queries in `bobgen-psql`.

### Changed

- Changed to non-cgo version of postgres parser.
- Changed the `dir` configuration for `bobgen-sql` to `pattern` and it now takes a glob pattern. This allows excluding certain files from being included (e.g. `.down.sql` files).

## [v0.33.1] - 2025-04-26

### Changed

- When a query returns only one column, instead of returning a struct with one field, it will return the type of the column. This is to make it easier to use the generated code.

### Fixed

- Fix panic when scanning returned rows from generated queries.

## [v0.33.0] - 2025-04-26

### Added

- Added support to generate code for `INSERT` queries in `bobgen-psql`.
- `clause.Confict` now takes `bob.Expression`, and the fields are now moved to a `clause.ConflictClause` struct.

### Changed

- Make grouped types in generated queries a type alias.

### Removed

- Remove `models.InsertWhere` in generated code since it is not correct.

### Fixed

- Fix issue with column query annotations in `bobgen-psql`.
- Fix issue with parsing multiple queries in the same file in `bobgen-psql`.
- Fix issue with correctly detecting the comment for the query annotation in `bobgen-psql`.
- Use a transaction in generated query tests.
- Account for LEFT, RIGHT and FULL joins when determining the nullability of a column.
- Generate WHERE helpers for `ON CONFLICT` clauses.

## [v0.32.0] - 2025-04-24

### Added

- Added templates for query generation.
- Added `clause.OrderBy.ClearOrderBy()`
- Added `expr.ToArgs` and `expr.ToArgGroup` functions to convert slices of a type to args.
- Add `queries` key to `bobgen-sql` and `bobgen-sqlite` configuration. This is used to specify what folder to search for queries in.
- Implement the Postgres query parser for `SELECT` statements.
- Implement the SQLite query parser for `SELECT` statements.
- Add templates for query generation.
- Add `camelCase` template function.
- Add types to the `orm` package to be used in generated queries. `orm.ArgWithPosition`, `orm.ModExpression`, `orm.ModExecQuery` and `orm.ModQuery`.
- Add function `orm.ArgsToExpression` for use in the generated code.
- Add `String()` method to `bob.QueryType`

### Fixed

- Update `mvdan.cc/gofumpt` and give precedence to toolchain when calculating the Go version. (thanks @isgj)
- Add custom comparison support when loading relationships.
- Fix issue with scanning Postgres inet type.
- Set `Arg` and `ArgGroup` to `NULL` if there are no values.
- Do not call `BeforeInsertHooks` in the insert mod of a view.
- Fix issue with retrieving inserted rows with the MySQL driver.
- Add custom comparison for relationship loading. (thanks @kostaspt)

### Changed

- `clause.With` now takes `bob.Expression` instead of `clause.CTE`. This makes it easier to use in generated queries without reconstruction an `CTE`.
- `clause.OrderBy` now takes `bob.Expression` instead of `clause.OrderDef`. This makes it easier to use in generated queries without reconstruction an `OrderDef`.
- `clause.Windows` now takes `bob.Expression` instead of `clause.NamedWindow`. This makes it easier to use in generated queries without reconstruction the window.
- `clause.For` renemaed to `clause.Locks` and can now take multiple locks.
- `clause.Fetch` now takes `any` instead of an integer.
- Several changes to the `drivers.Query` type as support is added for the new query parser.
- Enum types can now be matched by `db_type` in bobgen-psql as `schema.enum_type`. (thanks @abramlab)

### Removed

- Removed `clause.OrderBy.SetOrderBy()` as it was only being used to clear the set order by clauses.

## [v0.31.0] - 2025-03-26

### Added

- Added support for libSQL. (thanks @mbezhanov)
- Added support for declaring types inside the models package. (thanks @jacobmolby)

### Changed

- Generates error constants with unique indexes instead of unique constraints. (thanks @tlietz)

### Fixed

- Used `Equal` method for comparing decimals. (thanks @jalaziz)
- Update `golang.org/x/mod` dependency to enable parsing of Go 1.23 modules. (thanks @m110)

## [v0.30.0] - 2025-01-16

### Added

- Added a new field `QueryFolders` to `gen/drivers.DBInfo` for drivers to be able to include information about parsed queries.
- Added `gen/QueriesTemplates` which in the future will contain base templates for generating code for parsed qureries.
- Added a `QueryTemplate` field to `bobgen_helpers.Templates` for drivers to include additional templates for queries.
- Added a new reserved output key `queries`. This is handled specially for each query folder supplied by the driver.
- Added new `wm` package to each dialect for mods that modify `Window` clauses.
- Added a new method `Alias` for `View` struct, for each dialect. It returns the alias of the view. (thanks @Nitjsefni7)

### Changed

- Updated error constant generation to employ specific error types for making error matching easier. (thanks @mbezhanov)
- Collation in `clause.OrderDef` is now a string not an expression and is always quoted
- Calling `UpdateAll`, `DeleteAll` and `ReloadAll` on an empty model slice now returns nil without running any queries.
- `UNION`, `INTERSECT` and `EXCEPT` mods now append to the query instead of replacing it.
- Generated files now end with `.bob.go` instead of `.go` and are always cleaned up before generating new files. Singleton templates are now required to have a `.bob.go.tpl` extension.
- The expected structure for templates have been changed:
  - Previously, singleton templates should be kept in a `singleton` folder. Now, any template not inside a folder is considered a singleton template.
  - Previoulsy, templates in the root folder are merged and run for each table. Now, this will happen to templates in the `table/` folder.
  - Previoulsy, the entire file tree and every subdirectory is walked to find templates. Now only templates in the root folder and the `table/` folder are considered.
- Change `From` in `clause.Window` to `BasedOn` to avoid confusion with `FromPreceding` and `FromFollowing`. Also change `SetFrom` to `SetBasedOn`.
- Embed `clause.OrderBy` in `clause.Window` to make it possible to reuse `OrderBy` mods in window definitions.
- Change the `Definition` field in `clause.NamedWindow` from `any` to `clause.Window` for extra type safety.
- `sm.Window` now takes mods to modify the window clause.
- `fm.Over` now takes mods to modify the window for the window function.

### Deprecated

- Deprecated the `wipe` option to delete all files in the output folder. Files are now generated with a `.bob.go` extension and are always cleaned up before generating new files.

### Removed

- Remove redundatnt type parameters from `orm.ExecQuery`.
- Remove unnecessary interface in `orm.Query` and `orm.ExecQuery`.
- Remove the redundant `clause.IWindow` interface.
- Remove `dialect.WindowMod` and `dialect.WindowMods` which use chainable methods to modify `Window` clauses. This is now handled by the `wm` package which used mods.

### Fixed

- Fix random value generation for pq.Float64Array factory (thanks @felipeparaujo)
- Using the `UpdateMod()` and `DeleteMod()` methods on an empty model slice now appends `WHERE primary_key IN NULL` which will return no results. Instead of `WHERE primary_key IN ()` which is a syntax error.
- Ensure `net/netip` is imported for the `pgtypes.Inet` random expression (thanks @plunkettscott)
- Fix a data race when adding enum types.
- Fix missing schema in table alias in pkEQ and pkIN clauses (thanks @adatob).

## [v0.29.0] - 2024-11-20

### Added

- Added error constants for matching against both specific and generic unique constraint errors raised by the underlying database driver. (thanks @mbezhanov)
- Added support for regular expressions in the `only` and `except` table filters. (thanks @mbezhanov)
- Added `ContextualMods` which are similar to regular mods but take a context argument. They are applied whenever the query is built.  
  This makes it cleaner to do certain things, like populating the select columns of a model if none was explicitly added.  
  The previous way this was done was unreliable since using `q.MustBuild()` would not add the columns while `bob.MustBuild(q)` will add them correctly.
- `modelSlice.UpdateMod()` and `modelSlice.DeleteMod()` are new methods that returns a mod for update and delete queries on a slice of models.  
  It adds `WHERE pk IN (pk1, pk2, pk3, ...)` to the query, and also schedule running the **hooks**.
- Added `bob.ToMods` which a slice of structs that implement `bob.Mod[T]` to a Mod. This is useful since Go does not allow using a slice of structs as a slice of an interface the struct implements.
- Added `bob.HookableQuery` interface. If a query implements this interface, the method `RunHooks(ctx, exec)` will be called before the query is executed.
- Added `bob.HookableType` interface. If a type implements this interface, the method `AfterQueryHook(ctx, exec, bob.QueryType)` will be called after the query is executed.  
  This is how `AfterSeleect/Insert/Update/DeleteHooks` hooks are now implemented.
- Added `Type() QueryType` method to `bob.Query` to get the type of query it is. Available constants are `Unknown, Select, Insert, Update, Delete`.
- Postgres and SQLite Update/Delete queries now refresh the models after the query is executed. This is enabled by the `RETURNING` clause, so it is not available in MySQL.
- Added the `Case()` starter to all dialects to build `CASE` expressions. (thanks @k4n4ry)
- Added `bob.Named()` which is used to add named arguments to the query and bind them later.
- Added `bob.BindNamed` which takes an argument (struct, map, or a single value type) to be used to bind named arguments in a query. See changes to `bob.Prepare()` for details of which type can be used.
- Indexes now include more information such as the type, unique and comment fields.
- Constraints now include a comment field.
- Added `Checks` field to DBConstraints so that drivers can also load check constraints. (not yet supported by the SQLite driver).
- Added comments field to Table definitions.

### Changed

- `context.Context` is now passed to `Query.WriteQuery()` and `Expression.WriteSQL()` methods. This allows for more control over how the query is built and executed.  
  This change made is possible to delete some hacks and simplify the codebase.
  - The `Name()` and `NameAs()` methods of Views/Tables no longer need the context argument since the context will be passed when writing the expression. The API then becomes cleaner.
  - Preloading mods no longer need to store a context internally. `SetLoadContext()` and `GetLoadContext()` have removed.
  - The `ToExpr` field in `orm.RelSide` which was used for preloading is no longer needed and has been removed.
- Moved `orm.Hooks` to `bob.Hooks` since it should not be limited to only ORM queries.
- Moved `mods.QueryModFunc` to `bob.ModFunc` since it should be available to all packages.
- The mod capability for `orm.Setter` is now reversed. It should now be a mod for Insert and have a method that returns a mod for Update.  
   This makes more sense since one would at most use one setter during updates, but can use multiple setters in a bulk insert.
- `table.InsertQ` has been renamed to `table.Insert`. The old implementation of `Insert` has been removed.  
   The same functionality can be achieved in the following way:

  ```go
  //----------------------------------------------
  // OLD WAY
  //----------------------------------------------
  user, err := models.Users.Insert(ctx, db, setter) // insert one
  users, err := models.Users.InsertMany(ctx, db, setters...) // insert many

  //----------------------------------------------
  // NEW WAY
  //----------------------------------------------
  user, err := models.Users.Insert(setter).One(ctx, db) // insert one
  users, err := models.Users.Insert(setters[0], setters[1]).All(ctx, db) // insert many

  // For cases where you already have a slice of setters and you want to pass them all, you can use `bob.ToMods`
  users, err := models.Users.Insert(bob.ToMods(setters)).All(ctx, db) // insert many
  ```

- `table.UpdateQ` has been renamed to `table.Update`. The old implementation of `Update` has been removed.  
   The same functionality can be achieved by using `model.Update()` or `modelSlice.UpdateAll()`.
- `table.DeleteQ` has been renamed to `table.Delete`. The old implementation of `Delete` has been removed.  
   The same functionality can be achieved by using `modelSlice.DeleteAll()` or creating an `Delete` query using `table.Delete()`.
- `BeforeInsertHooks` now only takes a single `ModelSetter` at a time.  
   This is because it is not possible to know before executing the queries exactly how many setters are being used since additional rows can be inserted by applying another setter as a mod.
- `bob.Cache()` now requires an `Executor`. This is used to run any query hooks.
- `bob.Prepare()` now requires a type parameter to be used to bind named arguments. The type can either be:
  - A struct with fields that match the named arguments in the query
  - A map with string keys. When supplied, the values in the map will be used to bind the named arguments in the query.
  - When there is only a single named argument, one of the following can be used:
    - A primitive type (int, bool, string, etc)
    - `time.Time`
    - Any type that implements `driver.Valuer`.
- `Index` columns are no longer just strings, but are a struct to include more information such as the sort order.

### Removed

- Remove MS SQL artifacts. (thanks @mbezhanov)
- Remove redundant type parameter from `bob.Load`.
- Removed `Before/AfterUpsertMods`. Upserts are really just inserts with a conflict clause and should be treated as such.
- Removed `Insert/InsertMany/Upsert/UpsertMany` methods from `orm.Table` since they are not needed.  
  It is possible to do the same thing, with similar effor using the the `InsertQ` method (which is now renamed to `Insert`).
- Remove `Update` and `Delete` methods from `orm.Table` since they are not needed.  
  It is possible to do the same thing, with similar effor using the the `UpdateQ` and `DeleteQ` methods (which are now renamed to `Update` and `Delete`).
- `context.Context` and `bob.Executor` are no longer passed when creating a Table/ViewQuery. It is now passed at the point of execution with `Exec/One/All/Cursor`.
- Remove `Prepare` methods from table and view qureries. Since `bob.Prepare()` now takes a type parameter, it is not possible to prepare from a method since Go does not allow additional type parameters in methods.
- Removed the **Prisma** and **Atlas** code generation drivers. It is better for Bob to focus on being able to generate code from the database in the most robust and detailed way and if the user wants, they can use other tools (such as prisma and atlas) to manage migrations before the code generation.
- Removed `Expressions` from Index definitions. It is now merged with the `Columns` field with an `IsExpression` field to indicate if the column is an expression.

### Fixed

- Removed unnecessary import of `strings` in `bobfactory_random.go`.
- Fixed data races in unit tests. (thanks @mbezhanov)
- Fixed invalid SQL statements generated by `sm.OrderBy().Collate()`. (thanks @mbezhanov)
- Fixed a bug preventing specific columns from being excluded when generating models from SQLite. (thanks @mbezhanov)
- Fixed an issue where invalid code is generated if a configured relationship has `from_where` or `to_where`.
- Fixed `ModelSlice.ReloadAll()` method for models with multiple primary keys.

## [v0.28.1] - 2024-06-28

### Fixed

- Also add the enum to the type array if an array of the enum is added. This is to prvent issues if the enum is only used in an array.
- Handle null column names in expression indexes. (thanks @mbezhanov)
- CROSS JOINS now allow aliases

## [v0.28.0] - 2024-06-25

### Added

- Added the `pgtypes.Inet` for `inet` type in PostgreSQL. (thanks @gstarikov)
- Added the `pgtypes.Macaddr` for `macaddr` and `macaddr8` types in PostgreSQL.
- Added the `pgtypes.LSN` type for the `pg_lsn` type in PostgreSQL.
- Added the `pgtypes.TxIDSnapshot` type for the `txid_snapshot` type in PostgreSQL.
- Added the `pgtypes.TSVector` type for the `tsvector` type in PostgreSQL.
- Added `AliasOf` property to codegen type definitions to allow for defining types that have their own randomization logic.
- Added `DependsOn` property to codegen type definitions to allow for defining types that depend on other types. This ensures that necessary code for the dependent types is generated.
- Add `xml` type definition for custom randomization logic.
- Add the `Cast()` starter to all dialects to build `CAST(expr AS type)` expressions.
- Load index information for MySQL, PostgreSQL, and SQLite tables. (thanks @mbezhanov)

### Changed

- Changed the `parray` package to `pgtypes`.
- Moved `HStore` to the `pgtypes` package.
- Simplified how random expressions are written for types by using standalone functions instead of a single generic function.
- The default `DebugPrinter` now prints args a bit more nicely by using thier `Value()` method if they implement the `driver.Valuer` interface.
- Only generate 2 random values when testing random expressions.

### Removed

- Removed `types.Stringer[T]`. It makes assumptions for how the type should be scanned and is not reliable.

### Fixed

- Do not add `FROM` clause to `SELECT` queries that are used as subqueries.
- Enum values are now checked for validity after scanning.

## [v0.27.1] - 2024-06-05

### Fixed

- Fixed bug in `Count()` queries not removing the offset from the original query. (thanks @daddz)

## [v0.27.0] - 2024-06-05

### Added

- Add PreloadAs PreloadOption to override the join alias when preloading a relationship with a left join. (thanks @daddz)
- Add `AliasedAs()` method to `tableColumns` and `tableWhere` types to use a custom alias.
- Add `AliasedAs()` method to generated relationship join mods. This is avaible in two places:
  - one to change the alias of the table being queried

    ```go
    models.SelectJoins.Jets.AliasedAs("j").InnerJoin.Pilots(ctx)
    ```

  - and the other to change the alias of the relationship.

    ```go
    models.SelectJoins.Jets.InnerJoin.Pilots(ctx).AliasedAs("p")
    ```

- Add `fm` mods to all supported dialects (psql, mysql and sqlite). These are mods for functions and are used to modify the function call. For example:

  ```go
  // import "github.com/stephenafamo/bob/dialect/psql/fm"
  psql.F( "count", "*",)(fm.Filter(psql.Quote("status").EQ(psql.S("done"))))
  ```

- Add `MustCreate`, `MustCreateMany`, `CreateOrFail` and `CreateManyOrFail` methods to generated factory Templates

### Changed

- Change the function call point for generated relationship join mods. This reduces the amount of allocations and only does the work for the relationship being used.

  ```go
  // Before
  models.SelectJoins(ctx).Jets.InnerJoin.Pilots
  // After
  models.SelectJoins.Jets.InnerJoin.Pilots(ctx)
  ```

- Changed the `Count()` function on `Views` to clone the query instead of changing the existing one. This makes queries reusable and the `Count()` function to behave as one would expect.

  ```go
  // This now works as expected
  query := models.Jets.Query(ctx, db, /** list of various mods **/)
  count, err := query.Count()
  items, err := query.All()
  ```

- Changed how functions are modified. Instead of chained methods, the `F()` starter now returns a function which can be called with mods:

  ```go
  // Before
  psql.F( "count", "*",).FilterWhere(psql.Quote("status").EQ(psql.S("done"))),
  // After
  // import "github.com/stephenafamo/bob/dialect/psql/fm"
  psql.F( "count", "*",)(fm.Filter(psql.Quote("status").EQ(psql.S("done")))),
  ```

  This makes it possible to support more queries.

- Use `netip.Addr` instead of `netip.Prefix` for Postgres `cidr` type.
- Use `decimal.Decimal` instead of `string` for Postgres `money` type.
- Use `net.HardwareAddr` for Postgres `macaddr8` type, in addition to the `macaddr` type.
- Code generation now generates struct tags for the generated model Setters as well, if configured through the `Tags` configuration option. Previoulsy, only the model struct fields were tagged. (thanks @singhsays)

### Removed

- Remove `TableWhere` function from the generated code. It was not used by the rest of the generated code and offered no clear benefit.
- Removed `As` starter. It takes an `Expression` and is not needed since the `Expression` has an `As` method which can be used directly.

### Fixed

- Fix a bug with `types.Stringer[T]` where the wrong value was returned in the `Value()` method.

## [v0.26.1] - 2024-05-26

### Fixed

- Use `netip.Prefix` instead of `netip.Addr` for postgres inet column type. This makes it possible to contain a subnet.
- Allow underscores in enum variable names.
- Fix an issue with title casing enum values

## [v0.26.0] - 2024-05-21

### Added

- Add `bobgen-sql` a code generation driver for SQL schema files. Supports PostgreSQL and SQLite.
- Add new properties `compare_expr` and `compare_expr_imports` to the `types` configuration. This is used when comparing primary keys and in testing.
- Add `never_required` to relationships configuration. This makes sure the factories does not require the relationship to be set. Useful if you're not using foreign keys. (thanks @jacobmolby)
- Add wrapper types for Stringer, TextMarshaler/Unmarshaler, and BinaryMarshaler/Unmarshaler to the `types` configuration.
- Make generated enum types implement the `fmt.Stringer`, `encoding.TextMarshaler`, `encoding.TextUnmarshaler`, `encoding.BinaryMarshaler` and `encoding.BinaryUnmarshaler` interfaces.

### Fixed

- Properly detect reference columns for implicit foreign keys in SQLite.
- Fix panic when generating random values for nullable columns. (thanks @jacobmolby)
- Sort relationships and imports for deterministic generated code. (thanks @jacobmolby)
- Correctly allow `OVER ()` with an empty window definition in PostgreSQL. (thanks @relvacode)
- Set `GROUP BY` to `NULL` if there are no expressions to group by.
- Replace symbols in enum values with their unicode point to make them valid Go identifiers.
- Properly detect implicit foreign keys in SQLite.
- Fix issue with attaching multi-sided relationships. (thanks @jacobmolby)

## [v0.25.0] - 2024-01-20

### Changed

- Update `github.com/jaswdr/faker` dependency from `v1` to `v2`

## [v0.24.0] - 2024-01-20

### Added

- Add randomization for all primitive types
- Add test for factory type randomization
- Drivers are now required to send in type definitions for generated types
- Custom types can now be configured at a top level in the config file

### Changed

- Format generated files with `gofumpt`
- Replace key in `replacements` configuration is now a string referring to the type defined in the `types` configuration.

### Removed

- Remove `Imports` from column definition.

### Fixed

- `INTEGER` columns are now correctly generated as `int32` not `int`

## [v0.23.2] - 2024-01-04

### Fixed

- Fix panic when inferring `modify` for relationships with no primary key
- Skip factory enum generation if there are no enums
- Return `sql.ErrNoRows` when Insert/Upsert returns nothing

## [v0.23.1] - 2024-01-03

### Fixed

- Do not wrap `Setter.Expressions()` in parenthesis

## [v0.23.0] - 2024-01-03

### Added

- Add `bob.Cache()` which saves the built SQL and args to prevent rebuilding the same query multiple times.
- Add `As()` starter to alias expressions
- Add `OP()` builder method for using custom operators
- Add `table.InsertQ(ctx, db)` now includes the insert columns from the table model.
- It is now possible to configure additional constraints for code generation.
- Add `um.SetCol()` which maintains the old behavior of `um.Set()`.
- Generate additional `Expressions()` method for Setters to make it easier to use them in `um.Set()` or `im.Set()`.

### Changed

- Aliases configuration for code generation no longer has a top level `table` key
- When configuring relationships, `from_unique`, `to_unique`, `key_nullable` can no longer be configured. They are now inferred from the database.
- When configuring relationships, `to_key` has been changed to `modify` and should be set to `from`, `to` or `""` to indicate which side of the relationship to modify.
  If left empty, Bob will try to guess which side to modify based on the presence of primary keys and unique columns.
- `RelWhere.Value` is now `RelWhere.SQLValue`
- Change CONFLICT/DUPLICATE KEY UPDATE to use mods instead of a chainable methods.
- Change `um.Set()` to take a list of expressions.
- Rename Setter method from `Insert()` to `InsertMod()` to avoid confusion.

### Fixed

- Prevent generating duplicate relationships for many-to-many self-join relationships
- Correctly use table alias in generated relationship join mods
- Fix an issue where CTEs were encased in double parenthesis
- Fix invalid SQL generated when doing `JOIN USING`
- Correctly include "AS" in function query if alias is set
- Setters are also generated for tables that have relationships, even if they have no primary key
- Column aliases in CTEs are now correctly included in the final query
- Fix several issues with generating code for multi-sided relationships
- Fix an issue where loading many-to-many relationships cause no columns to be selected unless specified
- Fix an issue where many-to-many relationships would not be able to use nested loaders

## [v0.22.0] - 2023-08-18

### Added

- Expand expressions when used in Raw (thanks @RangelReale)
- Add `InsertQ`, `UpdateQ`, and `DeleteQ` methods to Table models to start INSERT, UPDATE and DELETE queries respectively.
- Allow column comment for replacement matching (thanks @jroenf)
- Add table query hooks to modify model queries
- Include `WhereOr` and `WhereAnd` to make it easier to combine multiple generated where clauses
- Print a warning if a replacement rule did not find a match (thanks @jacobmolby)

### Changed

- Export generated factory.Factory struct
- Allow Limit and Offset to be used as Arguments in PostgreSQL (thanks @RangelReale)
- Make model hooks take slices not single objects
- Return rows affected from `Exec()` method of view queries instead of `sql.Result`
- Chain comparison methods now take an `Expression` instead of `any`
- Table models now require the types to implement `orm.Table` and `orm.Setter` interfaces.

### Removed

- Remove UpdateAll and DeleteAll methods on the Table models.

### Fixed

- Honor Only and Except in sqlite driver
- Always surround subqueries with parenthesis when used as an expression
- Fix mysql `TablesInfo` method and make sure we don't exclude entire table when targeting columns (thanks @jacobmolby)
- Fix bug in sqlite foreign key and join table detection

## [v0.21.1] - 2023-05-22

### Fixed

- Fix `Upsert` and `UpsertAll` methods of `mysql.Table`

## [v0.21.0] - 2023-05-09

### Changed

- Force uniqueness of relationship names in `psql` driver

### Fixed

- Fix panic when attaching associated relationships
- Make getting a random integer for preloading thread-safe

## [v0.20.6] - 2023-04-25

### Fixed

- Check all members when loading relationships

## [v0.20.5] - 2023-04-14

### Fixed

- Fix panic in Insert/Attach Relationship loop

## [v0.20.4] - 2023-04-07

### Fixed

- Replace `huandu/go-clone` with `qdm12/reprint`

## [v0.20.3] - 2023-04-06

### Fixed

- Fix cloning bug by replacing `jinzhu/copier` with `huandu/go-clone`

## [v0.20.2] - 2023-04-05

### Fixed

- Account for windows when calculating models module path

## [v0.20.1] - 2023-04-04

### Fixed

- Update the generated code to use `github.com/gofrs/uuid/v5`
- Fix bug where auto-increment columns were marked as generated in the SQLite driver

## [v0.20.0] - 2023-04-03

### Added

- Add the `PreloadWhere` preload mod to filter what relation should be preloaded.
- `ViewQuery` now embeds `bob.BaseQuery` giving it additional methods like `Apply` and `Build`
- Add plugin support. Currently 3 plugin hooks are provided. `PlugState`, `PlugDBInfo` and `PlugTemplateData`.

### Changed

- Make `View.Name()` return a dialect-specific expression
- Improve `Debug` helpers.
  - `Debug` writes query output to stdout
  - `DebugToWriter` writes the query output to any `io.Writer` with a fallback to stdout.
  - `DebugToPrinter` prints the query with a given `bob.DebugPrinter`. Also falls back to stdout.
- Rename `OnlyColumns` to `PreloadOnly` and `ExceptColumns` to `PreloadExcept` to be more consistent with the newly added `PreloadWhere`.
- `JoinChain.On` now takes Expressions instead of `any`.
- `JoinChain.Using` now takes strings instead of `any`.
- Export `gen.TemplateData`

### Removed

- Remove `ILIKE` operator from MySQL since it is not supported.
- Removed `Destination()` method in driver interface.
- Removed `PackageName()` method in driver interface.

### Fixed

- Account for possible clashes between column and relationship alias
- Make `Preload` mods work the same way as other query mods
- Avoid overwriting manually flipped relationships.
- Account for potentially null relationship in Load methods

## [v0.19.1] - 2023-03-21

### Fixed

- Fix `On` method for JoinChain in `mysql` and `sqlite`

## [v0.19.0] - 2023-03-19

### Added

- Add `LIKE` and `ILIKE` operators
- Print generated files
- Add `no_reverse` option for user-configured relationships

### Changed

- Move common parts of loading to shared internal package

### Fixed

- Fix generated joins for multi-sided relationships

## [v0.18.2] - 2023-03-18

### Fixed

- Account for relationships with tables that do not have a primary key in models and factories
- Properly extract preloaders nested in `mods.QueryMods`
- Fix bug in preloading with multiple sides
- Fix issue with multi-sided relationships that include views

## [v0.18.1] - 2023-03-16

### Fixed

- Make self-referencing foreign keys work
- Tweak factory types to make collisions even less likely

## [v0.18.0] - 2023-03-12

### Changed

- Comparison methods now require an expression (`bob.Expression`)

### Removed

- No more `X` builder start function
- No more `P` builder method

## [v0.17.3] - 2023-03-11

### Fixed

- Fix bug with args in table updates
- Fix some typos in documentation (thanks @leonardtan13)

## [v0.17.2] - 2023-03-09

### Fixed

- Fix a bug when multiple multi-column foreign keys exist
- Multiple internal changes to the generator to make it easier to write a custom entrypoint
- More robust testing of code generatio
