github.com/stephenafamo/bob
v0.50.0
#913 most downloaded on Go modules
stephenafamo/bob
What this package is like to depend on
Last release 13 days ago
11 Aug 2026
Ships on a steady schedule
a new release about every 9 days
Most releases are documented
notes for 57 of 94 stable releases
1 version withdrawn
withdrawn after publishing
4 years old
329 releases · first in 2022
42 releases in the last 12 months
see the full history below
Release timeline
329 releases · Apr 2022 to Aug 2026Releases
latest 60 of 329-
v0.50.011 Aug 2026Release notes
Open source →Added
- Generated
dberrorspackages now include generic and per-table check-constraint errors for PostgreSQL, matched by constraint name forpqandpgxdrivers. (thanks @keithbro-imx)
Changed
- PostgreSQL single-column slice relationship loaders (
<Parent>Slice.<Rel>) and batch counts (<Parent>Slice.LoadCount<Rel>) now de-duplicate the key array bound to= ANY($1)when the key column can contain duplicates (a non-unique foreign key). The array is only a semi-join filter, so query results are unchanged — a slice of 10,000 parents sharing 50 related rows now binds 50 keys instead of 10,000. Keys that are unique by construction (the parent's own primary key or a uniquely-constrained column) and key types not comparable with==keep the previous plain loop, decided at codegen time (#740). (thanks @sandonemaki) - Generated through-relationship loaders (
Load<Rel>) no longer apply every query mod twice (once against a throwaway query to detect whether the user set columns, then again for real). The default columns are now added by a deferredbob.ModFuncduring the single real application — the same patternView.Queryuses — and the join-key slice is pre-allocated to the parent slice length. Generated SQL is unchanged (#740). (thanks @sandonemaki)
Fixed
- Fixed the PostgreSQL code generator's query parser renumbering each reference to a repeated query parameter (
$N) as a distinct argument (e.g.id = $1 OR parent_id = $1generating$1/$2), which changed the meaning of the generated query mods. Repeated$Nreferences now map to a single generated parameter (#745). (thanks @dmakushin)
New Contributors
- @dmakushin made their first contribution in #745
- @keithbro-imx made their first contribution in #717
Full Changelog: v0.49.0...v0.50.0
Release notes
Open source →Added
- Generated
dberrorspackages now include generic and per-table check-constraint errors for PostgreSQL, matched by constraint name forpqandpgxdrivers. (thanks @keithbro-imx)
Changed
- PostgreSQL single-column slice relationship loaders (
<Parent>Slice.<Rel>) and batch counts (<Parent>Slice.LoadCount<Rel>) now de-duplicate the key array bound to= ANY($1)when the key column can contain duplicates (a non-unique foreign key). The array is only a semi-join filter, so query results are unchanged — a slice of 10,000 parents sharing 50 related rows now binds 50 keys instead of 10,000. Keys that are unique by construction (the parent's own primary key or a uniquely-constrained column) and key types not comparable with==keep the previous plain loop, decided at codegen time (#740). (thanks @sandonemaki) - Generated through-relationship loaders (
Load<Rel>) no longer apply every query mod twice (once against a throwaway query to detect whether the user set columns, then again for real). The default columns are now added by a deferredbob.ModFuncduring the single real application — the same patternView.Queryuses — and the join-key slice is pre-allocated to the parent slice length. Generated SQL is unchanged (#740). (thanks @sandonemaki)
Fixed
- Fixed the PostgreSQL code generator's query parser renumbering each reference to a repeated query parameter (
$N) as a distinct argument (e.g.id = $1 OR parent_id = $1generating$1/$2), which changed the meaning of the generated query mods. Repeated$Nreferences now map to a single generated parameter (#745). (thanks @dmakushin)
- Generated
-
v0.49.1-0.20260804090146-1464858665b304 Aug 2026 pre-releaseNothing published for this version
-
v0.49.1-0.20260720163148-e48b781d0c8620 Jul 2026 pre-releaseNothing published for this version
-
v0.49.1-0.20260720123524-96dafaa3dcf120 Jul 2026 pre-releaseNothing published for this version
-
v0.49.020 Jul 2026Release notes
Open source →Added
- Added
bob.NextUniqueInt()for generating unique SQL alias suffixes (#719). (thanks @atzedus) - Code generation now emits a reflection-free
scan.Mapperper 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, andInsert/Update/DeletewithRETURNING— scans without the per-row reflection ofscan.StructMapper. (thanks @sandonemaki) - Generated
Wherestructs now include relationship filters under anRfield (e.g.SelectWhere.Pilots.R.HasJets(filters ...bob.Mod[*dialect.SelectQuery])) that filter rows by the existence of related rows, using a correlatedEXISTSsubquery (semi-join) built from the schema's relationship definitions. TheRnamespace mirrors the model struct and keeps the filters from colliding with column names. Unlike filtering throughSelectJoins, this does not multiply parent rows, soDISTINCTis not needed andCount()/LIMIT-based pagination stay correct (#722). (thanks @sandonemaki)
Changed
NewViewxandNewTablexin thepsql,mysqlandsqlitedialects now take ascan.Mapper[T]argument used for all queries built from the view/table. Passnilto keep the previous reflection-basedscan.StructMapperbehaviour.NewView/NewTableare 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 auuidcolumn (#730). - Fixed the counts plugin's generated
Cfield reusing therelation_tagstruct tag, which collided with the relationsRfield and causedencoding/jsonto drop both fields when a real tag name was configured. TheCfield now uses a dedicatedrelation_tag_countconfig option (default"-"). (thanks @jacobmolby) - Fixed generated join alias suffixes using
randInt(), which could produce negative values whenmaphash.Hash.Sum64()overflowedint64(#719). Generated join mods now usebob.NextUniqueInt()instead. (thanks @atzedus) - Fixed
orm.Query.Clone()dropping theScanner, which madeAll/One/Cursor/Eachon a cloned query panic with a nil pointer dereference. (thanks @sandonemaki) - Fixed column_order on
*selectors in sql queries in postgres
New Contributors
- @Leonard013 made their first contribution in #734
Full Changelog: v0.48.0...v0.49.0
Release notes
Open source →Added
- Added
bob.NextUniqueInt()for generating unique SQL alias suffixes (#719). (thanks @atzedus) - Code generation now emits a reflection-free
scan.Mapperper 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, andInsert/Update/DeletewithRETURNING— scans without the per-row reflection ofscan.StructMapper. (thanks @sandonemaki) - Generated
Wherestructs now include relationship filters under anRfield (e.g.SelectWhere.Pilots.R.HasJets(filters ...bob.Mod[*dialect.SelectQuery])) that filter rows by the existence of related rows, using a correlatedEXISTSsubquery (semi-join) built from the schema's relationship definitions. TheRnamespace mirrors the model struct and keeps the filters from colliding with column names. Unlike filtering throughSelectJoins, this does not multiply parent rows, soDISTINCTis not needed andCount()/LIMIT-based pagination stay correct (#722). (thanks @sandonemaki)
Changed
NewViewxandNewTablexin thepsql,mysqlandsqlitedialects now take ascan.Mapper[T]argument used for all queries built from the view/table. Passnilto keep the previous reflection-basedscan.StructMapperbehaviour.NewView/NewTableare unchanged. (thanks @sandonemaki)- JOIN a DISTINCT unnest(...) for composite-key relationship loaders & counts on PostgreSQL. (thanks @sandonemaki)
Preloadnow shares a single related-struct instance between all parent rows with the same join key, instead of building an identical instance per parent row — the same semantics asThenLoad. The emitted SQL is unchanged; construction, nested loader collection and mapping now run once per distinct related row, which significantly reduces time, allocations and retained memory on high-duplication workloads. Preloaded structs should be treated as read-only: code that mutates a preloaded struct and relies on each parent having its own copy must copy the struct first. (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 auuidcolumn (#730). - Fixed the counts plugin's generated
Cfield reusing therelation_tagstruct tag, which collided with the relationsRfield and causedencoding/jsonto drop both fields when a real tag name was configured. TheCfield now uses a dedicatedrelation_tag_countconfig option (default"-"). (thanks @jacobmolby) - Fixed generated join alias suffixes using
randInt(), which could produce negative values whenmaphash.Hash.Sum64()overflowedint64(#719). Generated join mods now usebob.NextUniqueInt()instead. (thanks @atzedus) - Fixed
orm.Query.Clone()dropping theScanner, which madeAll/One/Cursor/Eachon a cloned query panic with a nil pointer dereference. (thanks @sandonemaki) - Fixed column_order on
*selectors in sql queries in postgres
- Added
-
v0.48.1-0.20260720000131-2786e9cc413720 Jul 2026 pre-releaseNothing published for this version
-
v0.48.1-0.20260718081556-f17f6493445e18 Jul 2026 pre-releaseNothing published for this version
-
v0.48.1-0.20260711000130-95f703bdc85a11 Jul 2026 pre-releaseNothing published for this version
-
v0.48.026 Jun 2026Release notes
Open source →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 withcol = ANY($1)instead ofcol IN (SELECT unnest($1)), so the query planner can use an index scan on the foreign key instead of aSeq Scan + Hash Semi Join. Composite-key relationships keep the existingIN (SELECT unnest(...))form. (thanks @sandonemaki)
Fixed
- Fixed PostgreSQL generated query parsing for CTEs that use table functions in
FROM(for exampleunnest(...) AS alias), which could incorrectly widen CTE spans and generate malformed query mods such as duplicated outerSELECTprojections.
Full Changelog: v0.47.0...v0.48.0
Release notes
Open source →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 withcol = ANY($1)instead ofcol IN (SELECT unnest($1)), so the query planner can use an index scan on the foreign key instead of aSeq Scan + Hash Semi Join. Composite-key relationships keep the existingIN (SELECT unnest(...))form. (thanks @sandonemaki)
Fixed
- Fixed PostgreSQL generated query parsing for CTEs that use table functions in
FROM(for exampleunnest(...) AS alias), which could incorrectly widen CTE spans and generate malformed query mods such as duplicated outerSELECTprojections.
- PostgreSQL single-column relationship loaders — both the slice relationship query (
-
v0.47.1-0.20260626200259-bf3b99b5ce8f26 Jun 2026 pre-releaseNothing published for this version
-
v0.47.1-0.20260622201228-35d9c14c468822 Jun 2026 pre-releaseNothing published for this version
-
v0.47.022 Jun 2026Release notes
Open source →Added
- Added
column_orderconfig 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
RunInTxto passbob.Transactioninstead ofbob.Executor
New Contributors
Full Changelog: v0.46.0...v0.47.0
Release notes
Open source →Added
- Added
column_orderconfig 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
RunInTxto passbob.Transactioninstead ofbob.Executor
- Added
-
v0.46.1-0.20260611114504-576a98a3333211 Jun 2026 pre-releaseNothing published for this version
-
v0.46.011 Jun 2026Release notes
Open source →Added
With()on generated queries as a more ergonomic method to add mods on top of generated queries (thanks @daddz)- Added
Asc()/Desc()/...helpers tosm.OrderCombinedfor PostgreSQL/MySQL (thanks @daddz) - Added SQLite
um.SetCols(columns...)andim.SetCols(columns...)for tuple assignment inUPDATE ... SETandON CONFLICT DO UPDATE SET(.ToExprs(...),.ToRow(...),.ToQuery(...)). SQLite renders(cols) = (exprs...); PostgreSQLToRowstill emitsROW (...). MySQL does not support tuple assignment — use multipleSetColcalls. (thanks @atzedus)
Fixed
- Fixed generated
Setter.Applywrapping all insert values in a singleExpressionFunc, which preventedBeforeInsertHooksand query mods from modifying individual column values viaq.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/EXCEPTqueries dropping or misrouting the first operand'sORDER BY/LIMIT/OFFSETinto the combined-result clauses. (thanks @daddz) - Fixed PostgreSQL
um/dmstandalone join mods (InnerJoin,LeftJoin, etc.) applied beforeum.From(...)/dm.Using(...): the join is now preserved and attached to the nextFROM/USINGfrom_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 primaryFROMsource. (thanks @atzedus)
Changed
- Moved PostgreSQL
SetColstuple-assignment builder fromdialect/psql/dialect/setcols.goto sharedclause/setcols.go(clause.NewSetCols,clause.SetColsOptions). Dialect wrappers configureToRowviaSetColsOptions.RowPrefix(e.g."ROW"on PostgreSQL). (thanks @atzedus) EQcomparisons passed toSET/ON CONFLICT DO UPDATE SET/MERGE ... UPDATE SET/ MySQLON DUPLICATE KEY UPDATErender without the extra parentheses used inWHERE/ON(e.g.SET "users"."name" = $1vsWHERE ("users"."name" = $1)). (thanks @atzedus)NameAsExpr()on dialectView/Tabletypes (PostgreSQL, SQLite, MySQL) omits a redundantASwhen the alias matches the table name (for exampleFROM "users"instead ofFROM "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 customcompare_expr(e.g.[]byte) fall back to the original nested loop, so generated behaviour is unchanged. (thanks @sandonemaki)
New Contributors
- @sandonemaki made their first contribution in #706
Full Changelog: v0.45.0...v0.46.0
Release notes
Open source →Added
With()on generated queries as a more ergonomic method to add mods on top of generated queries (thanks @daddz)- Added
Asc()/Desc()/...helpers tosm.OrderCombinedfor PostgreSQL/MySQL (thanks @daddz) - Added SQLite
um.SetCols(columns...)andim.SetCols(columns...)for tuple assignment inUPDATE ... SETandON CONFLICT DO UPDATE SET(.ToExprs(...),.ToRow(...),.ToQuery(...)). SQLite renders(cols) = (exprs...); PostgreSQLToRowstill emitsROW (...). MySQL does not support tuple assignment — use multipleSetColcalls. (thanks @atzedus)
Fixed
- Fixed generated
Setter.Applywrapping all insert values in a singleExpressionFunc, which preventedBeforeInsertHooksand query mods from modifying individual column values viaq.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/EXCEPTqueries dropping or misrouting the first operand'sORDER BY/LIMIT/OFFSETinto the combined-result clauses. (thanks @daddz) - Fixed PostgreSQL
um/dmstandalone join mods (InnerJoin,LeftJoin, etc.) applied beforeum.From(...)/dm.Using(...): the join is now preserved and attached to the nextFROM/USINGfrom_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 primaryFROMsource. (thanks @atzedus)
Changed
- Moved PostgreSQL
SetColstuple-assignment builder fromdialect/psql/dialect/setcols.goto sharedclause/setcols.go(clause.NewSetCols,clause.SetColsOptions). Dialect wrappers configureToRowviaSetColsOptions.RowPrefix(e.g."ROW"on PostgreSQL). (thanks @atzedus) EQcomparisons passed toSET/ON CONFLICT DO UPDATE SET/MERGE ... UPDATE SET/ MySQLON DUPLICATE KEY UPDATErender without the extra parentheses used inWHERE/ON(e.g.SET "users"."name" = $1vsWHERE ("users"."name" = $1)). (thanks @atzedus)NameAsExpr()on dialectView/Tabletypes (PostgreSQL, SQLite, MySQL) omits a redundantASwhen the alias matches the table name (for exampleFROM "users"instead ofFROM "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 customcompare_expr(e.g.[]byte) fall back to the original nested loop, so generated behaviour is unchanged. (thanks @sandonemaki)
-
v0.45.1-0.20260602130909-c18ba1cb050102 Jun 2026 pre-releaseNothing published for this version
-
v0.45.028 May 2026Release notes
Open source →Added
- Added
Schema()method to dialectViewtypes (PostgreSQL, SQLite). (thanks @atzedus) - Added
ColumnsExpr()method onpsql.Viewfor parity with MySQL and SQLite views. (thanks @atzedus) - Added
um.SetExpr/im.SetExpr/mm.SetExprfor SET (and PostgreSQL/SQLiteim.SetExprforON CONFLICT DO UPDATE SET) when the assignment LHS is a qualified or arbitrary expression — passdialect.Quote(...)or anotherbob.Expression.SetCol/UpdateColremain for a single column name (quoted automatically). (thanks @atzedus)
Changed
- BREAKING:
psql.F/mysql.F/sqlite.Fanddialect.NewFunctionnow takename any(wasstring). The name is rendered withbob.Express; use a string for a literal function name ordialect.Quote("schema", "fn")for qualified names. (thanks @atzedus) - BREAKING:
mods.Setis now a struct with aCol anyfield instead of a[]stringalias.um.SetCol/im.SetCol/mm.SetCol(and MySQLim.UpdateCol) take astringcolumn name and quote it automatically; useSetExprfor qualified or arbitrary LHS expressions.SetCol(...).To(...)/SetExpr(...).To(...)implementbob.Expressionand can be passed toum.Set/im.Set/mm.Setto 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, andsm.ForKeySharenow taketables ...anyinstead oftables ...string. Passpsql.Quote(...)(or anotherExpression) for each locked relation (#693). (thanks @atzedus) - BREAKING: MySQL
sm.ForUpdateandsm.ForSharenow taketables ...anywith the same semantics as PostgreSQL (mysql.Quote(...)when needed). (thanks @atzedus) - BREAKING:
clause.Lock.Tablesis now[]anyinstead of[]string(used byFOR UPDATE/FOR SHARErendering). (thanks @atzedus) - BREAKING:
View/TableName()now returns the bare table (or view) name asstring. In v0.44.0,Name()returned a dialectExpression(qualified table reference for SQL). That role moved to new methods:NameExpr()— whatName()did in v0.44.0 (on PostgreSQL and SQLite, respectsUseSchemawhen schema was generated empty)NameAsExpr()— whatNameAs()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(); useUsers.Name()when you need the unqualified name string. On PostgreSQL and SQLite,Schema()still returns the schema when set.
- Codegen templates and
orm.Preloadnow useNameExpr()/NameAsExpr()instead ofName()/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, SQLiteINDEXED BY) and PostgreSQLMERGE/SetColscolumn lists, table-function column definitions, and MySQL optimizer-hint table lists. Simple identifier parameters are quoted automatically; passdialect.Quote(...)for qualified names inanyslots (From,OnConflict,FOR UPDATE OF, etc.). (thanks @atzedus) - Fixed PostgreSQL
sm.Fromclearing joins already on theFROMfrom_item (e.g.sm.CrossJoinbeforesm.From) becauseSelectQuery.AppendTableRefreplaced the entire embeddedFROMtable ref. Existing joins are merged into the new primary table ref. (thanks @atzedus) - Fixed
FOR UPDATE/FOR SHAREOFtable lists: passpsql.Quote(...)/mysql.Quote(...)so names with spaces or qualification render correctly (#693). (thanks @atzedus) - Fixed MySQL
sm.From(...).UseIndex/ForceIndex/IgnoreIndex(and*ForJoin/*ForOrderBy/*ForGroupByvariants) not appearing in generated SQL becauseFromChain.Applydid not copyIndexHintsonto 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.Keyintobuild*ColumnsandpkEQ/pkIN, but dialectView/Tabletypes useschema.tableasAlias()wheneverschemais set at construction. That mismatch produced SQL such as`users`.`id`inWHEREwhileFROMused`myapp`.`users` AS `myapp.users`(columns and primary-key expressions did not match the table alias fromNameAsExpr()). Templates now use atableColumnAliashelper:schema.namewhenschemais set, otherwisetable.Key. (thanks @atzedus) - Fix issue with overwriting unique constraints for tables beloging to other schemas. . (thanks @eaglehuntt and @MD-Mushfiqur123)
New Contributors
- @MD-Mushfiqur123 made their first contribution in #699
- @eaglehuntt made their first contribution in #699
Full Changelog: v0.44.0...v0.45.0
Release notes
Open source →Added
- Added
Schema()method to dialectViewtypes (PostgreSQL, SQLite). (thanks @atzedus) - Added
ColumnsExpr()method onpsql.Viewfor parity with MySQL and SQLite views. (thanks @atzedus) - Added
um.SetExpr/im.SetExpr/mm.SetExprfor SET (and PostgreSQL/SQLiteim.SetExprforON CONFLICT DO UPDATE SET) when the assignment LHS is a qualified or arbitrary expression — passdialect.Quote(...)or anotherbob.Expression.SetCol/UpdateColremain for a single column name (quoted automatically). (thanks @atzedus)
Changed
- BREAKING:
psql.F/mysql.F/sqlite.Fanddialect.NewFunctionnow takename any(wasstring). The name is rendered withbob.Express; use a string for a literal function name ordialect.Quote("schema", "fn")for qualified names. (thanks @atzedus) - BREAKING:
mods.Setis now a struct with aCol anyfield instead of a[]stringalias.um.SetCol/im.SetCol/mm.SetCol(and MySQLim.UpdateCol) take astringcolumn name and quote it automatically; useSetExprfor qualified or arbitrary LHS expressions.SetCol(...).To(...)/SetExpr(...).To(...)implementbob.Expressionand can be passed toum.Set/im.Set/mm.Setto 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, andsm.ForKeySharenow taketables ...anyinstead oftables ...string. Passpsql.Quote(...)(or anotherExpression) for each locked relation (#693). (thanks @atzedus) - BREAKING: MySQL
sm.ForUpdateandsm.ForSharenow taketables ...anywith the same semantics as PostgreSQL (mysql.Quote(...)when needed). (thanks @atzedus) - BREAKING:
clause.Lock.Tablesis now[]anyinstead of[]string(used byFOR UPDATE/FOR SHARErendering). (thanks @atzedus) - BREAKING:
View/TableName()now returns the bare table (or view) name asstring. In v0.44.0,Name()returned a dialectExpression(qualified table reference for SQL). That role moved to new methods:NameExpr()— whatName()did in v0.44.0 (on PostgreSQL and SQLite, respectsUseSchemawhen schema was generated empty)NameAsExpr()— whatNameAs()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(); useUsers.Name()when you need the unqualified name string. On PostgreSQL and SQLite,Schema()still returns the schema when set.
- Codegen templates and
orm.Preloadnow useNameExpr()/NameAsExpr()instead ofName()/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, SQLiteINDEXED BY) and PostgreSQLMERGE/SetColscolumn lists, table-function column definitions, and MySQL optimizer-hint table lists. Simple identifier parameters are quoted automatically; passdialect.Quote(...)for qualified names inanyslots (From,OnConflict,FOR UPDATE OF, etc.). (thanks @atzedus) - Fixed PostgreSQL
sm.Fromclearing joins already on theFROMfrom_item (e.g.sm.CrossJoinbeforesm.From) becauseSelectQuery.AppendTableRefreplaced the entire embeddedFROMtable ref. Existing joins are merged into the new primary table ref. (thanks @atzedus) - Fixed
FOR UPDATE/FOR SHAREOFtable lists: passpsql.Quote(...)/mysql.Quote(...)so names with spaces or qualification render correctly (#693). (thanks @atzedus) - Fixed MySQL
sm.From(...).UseIndex/ForceIndex/IgnoreIndex(and*ForJoin/*ForOrderBy/*ForGroupByvariants) not appearing in generated SQL becauseFromChain.Applydid not copyIndexHintsonto 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.Keyintobuild*ColumnsandpkEQ/pkIN, but dialectView/Tabletypes useschema.tableasAlias()wheneverschemais set at construction. That mismatch produced SQL such as`users`.`id`inWHEREwhileFROMused`myapp`.`users` AS `myapp.users`(columns and primary-key expressions did not match the table alias fromNameAsExpr()). Templates now use atableColumnAliashelper:schema.namewhenschemais set, otherwisetable.Key. (thanks @atzedus) - Fix issue with overwriting unique constraints for tables beloging to other schemas. (thanks @eaglehuntt and @MD-Mushfiqur123)
- Added
-
v0.44.1-0.20260528001901-8bd1162b771a28 May 2026 pre-releaseNothing published for this version
-
v0.44.1-0.20260525094416-24e585f7dd2a25 May 2026 pre-releaseNothing published for this version
-
v0.44.1-0.20260521235148-3a2d7847922021 May 2026 pre-releaseNothing published for this version
-
v0.44.021 May 2026Release notes
Open source →Added
- Added PostgreSQL
MERGEstatement SQL parser used for sql-to-code generation (thanks @atzedus) - Added
R.Loadedto generated models, a nested struct with oneboolper 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 byLoad*,Preload,ThenLoad, factory builds, and to-oneAttach/Insertops. TheLoadedalias can be changed in the bob config. (thanks @jacobmolby) - Added
As(alias)method tobob.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() stringmethod. (thanks @atzedus) - Added
expr.ColumnsExpraccessor methods:Parent() []string,AggFunc() [2]string,AliasPrefix() string, andAliasDisabled() 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.ParensOmitterinterface withShouldOmitParens() boolto let expressions opt out of automatic parenthesis wrapping in expression builders. (thanks @atzedus) - Added PostgreSQL
RETURNING WITH (OLD AS ..., NEW AS ...)support forINSERT,UPDATE,DELETE, andMERGEquery builders, including fluent modifiers:im/um/dm/mm.Returning(...).WithOldAs(...).WithNewAs(...). (thanks @atzedus)- Note:
bobgen-psqlsql-to-code parsing for this syntax is currently blocked by upstream PostgreSQL parser dependency support.
- Note:
- Added PostgreSQL
TABLESAMPLE ... REPEATABLE ...support via fluent modifiers onsm.From(...)and join chains. (thanks @atzedus) - Added PostgreSQL
JOIN ... USING (...) AS aliassupport viaUsingAs(alias, cols...)on psql join chains. (thanks @atzedus) - Added PostgreSQL GROUP BY grouping-element helpers:
sm.Grouping(...),sm.Rollup(...),sm.Cube(...), andsm.GroupingSets(...). (thanks @atzedus) - Added PostgreSQL
im.ConflictTarget(...)helper for composingON CONFLICTtarget 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 renderWHERE CURRENT OF <cursor>. (thanks @atzedus) - Added
expr.NoSepsentinel to join expressions without any separator. The existingexpr.Joindefault (space) is unchanged. (thanks @atzedus) - Added
im.Excluded(column)helper (PostgreSQL and SQLite) forON CONFLICT DO UPDATEassignments — renders asEXCLUDED."col"with no extra space, reused internally byim.SetExcluded(...)and available for direct use inim.SetCol(...).To(...). (thanks @atzedus) - Added PostgreSQL
psql.TableFunctions(funcs)andsm.FromFunction/um.FromFunction/dm.UsingFunctionhelpers that returnbob.Expressionfor table-functionfrom_itemsources (ROWS FROM (...)when multiple functions are given). (thanks @atzedus) - Added PostgreSQL
um.From(table, joins...)anddm.Using(table, joins...)variadic join arguments so each appendedfrom_itemcan include inlineINNER JOIN,LEFT JOIN,CROSS JOIN, etc. (JoinChainbuilders). (thanks @atzedus) - Added
bobgen-psqlsupport for multipleUPDATE ... FROM/DELETE ... USINGsources: sql-to-code emitsAppendTableRef(...)per parsedfrom_itemand resolves column sources from every item. (thanks @atzedus)
Changed
- BREAKING: Renamed the generated
ThenLoadCountvariable toSelectThenLoadCountfor naming consistency withSelectThenLoad/InsertThenLoad/UpdateThenLoad. Update call sites frommodels.ThenLoadCount.X.Ytomodels.SelectThenLoadCount.X.Y. (thanks @jacobmolby) - BREAKING:
mm.SetCol()now returnsmods.Set[*mm.UpdateAction]instead of a customSetChaintype..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 supportWITH RECURSIVEin MERGE statements. (thanks @atzedus) - BREAKING: Generated
*Columnsaccessor fields now return a dialect-specific wrapper type (e.g.,userColumn) instead of plaindialect.Expression. The wrapper still implementsdialect.Expressionand avoids extra auto-parentheses in expression builders. Use.Expressiononly when you explicitly need the embedded expression value. (thanks @atzedus) - BREAKING: PostgreSQL
UPDATE ... FROMandDELETE ... USINGadditional sources now live inUpdateQuery.FromItems/DeleteQuery.UsingItemsinstead of the embeddedclause.TableRefon the query struct. Eachum.From(...)ordm.Using(...)appends one comma-separatedfrom_item(last call no longer wins). Useum.Table(...)/dm.From(...)for the update/delete target table. (thanks @atzedus) - BREAKING: PostgreSQL
sm.FromFunctionandum.FromFunctionno longer returnFromChainor applyFROM/USINGby themselves. They returnbob.Expressionand must be passed tosm.From(...)/um.From(...)/dm.Using(...)— e.g.sm.From(sm.FromFunction(psql.F("generate_series", 1, 3)()))instead ofsm.FromFunction(...). Aliasing and other table modifiers belong onsm.From(...)/um.From(...). (thanks @atzedus) - BREAKING: PostgreSQL
sm.From/FromChainforSelectQuerynow set theFROMsource viaAppendTableRef(replace semantics) instead ofSetTable/SetTableAliason afromableinterface. (thanks @atzedus) - BREAKING: PostgreSQL
um/dmjoin helpers (InnerJoin,LeftJoin,CrossJoin, etc.) returnJoinChain[*UpdateQuery]/JoinChain[*DeleteQuery]. Use them inum.From(table, joins...)/dm.Using(table, joins...), or as standalone mods afterum.From/dm.Using—AppendJointhen attaches to the lastFromItems/UsingItemsentry. (thanks @atzedus) - BREAKING: PostgreSQL psql join chain modifiers
.Natural(),.On(),.OnEQ(),.Using(), and.UsingAs()now returnJoinChainfor fluent chaining instead ofbob.Mod. (thanks @atzedus)
Fixed
- Fix PostgreSQL
sm.Fromreplacing a previousFROMwithout clearing a stale table alias when the new source has no alias. (thanks @atzedus) - Fix PostgreSQL
sm.With(...).SearchBreadth(...)renderingSEARCH DEPTHinstead ofSEARCH BREADTHin 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 usingtype_system: "database/sql"anduuid_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)
New Contributors
Full Changelog: v0.43.0...v0.44.0
Release notes
Open source →Added
- Added PostgreSQL
MERGEstatement SQL parser used for sql-to-code generation (thanks @atzedus) - Added
R.Loadedto generated models, a nested struct with oneboolper 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 byLoad*,Preload,ThenLoad, factory builds, and to-oneAttach/Insertops. TheLoadedalias can be changed in the bob config. (thanks @jacobmolby) - Added
As(alias)method tobob.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() stringmethod. (thanks @atzedus) - Added
expr.ColumnsExpraccessor methods:Parent() []string,AggFunc() [2]string,AliasPrefix() string, andAliasDisabled() 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.ParensOmitterinterface withShouldOmitParens() boolto let expressions opt out of automatic parenthesis wrapping in expression builders. (thanks @atzedus) - Added PostgreSQL
RETURNING WITH (OLD AS ..., NEW AS ...)support forINSERT,UPDATE,DELETE, andMERGEquery builders, including fluent modifiers:im/um/dm/mm.Returning(...).WithOldAs(...).WithNewAs(...). (thanks @atzedus)- Note:
bobgen-psqlsql-to-code parsing for this syntax is currently blocked by upstream PostgreSQL parser dependency support.
- Note:
- Added PostgreSQL
TABLESAMPLE ... REPEATABLE ...support via fluent modifiers onsm.From(...)and join chains. (thanks @atzedus) - Added PostgreSQL
JOIN ... USING (...) AS aliassupport viaUsingAs(alias, cols...)on psql join chains. (thanks @atzedus) - Added PostgreSQL GROUP BY grouping-element helpers:
sm.Grouping(...),sm.Rollup(...),sm.Cube(...), andsm.GroupingSets(...). (thanks @atzedus) - Added PostgreSQL
im.ConflictTarget(...)helper for composingON CONFLICTtarget 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 renderWHERE CURRENT OF <cursor>. (thanks @atzedus) - Added
expr.NoSepsentinel to join expressions without any separator. The existingexpr.Joindefault (space) is unchanged. (thanks @atzedus) - Added
im.Excluded(column)helper (PostgreSQL and SQLite) forON CONFLICT DO UPDATEassignments — renders asEXCLUDED."col"with no extra space, reused internally byim.SetExcluded(...)and available for direct use inim.SetCol(...).To(...). (thanks @atzedus) - Added PostgreSQL
psql.TableFunctions(funcs)andsm.FromFunction/um.FromFunction/dm.UsingFunctionhelpers that returnbob.Expressionfor table-functionfrom_itemsources (ROWS FROM (...)when multiple functions are given). (thanks @atzedus) - Added PostgreSQL
um.From(table, joins...)anddm.Using(table, joins...)variadic join arguments so each appendedfrom_itemcan include inlineINNER JOIN,LEFT JOIN,CROSS JOIN, etc. (JoinChainbuilders). (thanks @atzedus) - Added
bobgen-psqlsupport for multipleUPDATE ... FROM/DELETE ... USINGsources: sql-to-code emitsAppendTableRef(...)per parsedfrom_itemand resolves column sources from every item. (thanks @atzedus)
Changed
- BREAKING: Renamed the generated
ThenLoadCountvariable toSelectThenLoadCountfor naming consistency withSelectThenLoad/InsertThenLoad/UpdateThenLoad. Update call sites frommodels.ThenLoadCount.X.Ytomodels.SelectThenLoadCount.X.Y. (thanks @jacobmolby) - BREAKING:
mm.SetCol()now returnsmods.Set[*mm.UpdateAction]instead of a customSetChaintype..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 supportWITH RECURSIVEin MERGE statements. (thanks @atzedus) - BREAKING: Generated
*Columnsaccessor fields now return a dialect-specific wrapper type (e.g.,userColumn) instead of plaindialect.Expression. The wrapper still implementsdialect.Expressionand avoids extra auto-parentheses in expression builders. Use.Expressiononly when you explicitly need the embedded expression value. (thanks @atzedus) - BREAKING: PostgreSQL
UPDATE ... FROMandDELETE ... USINGadditional sources now live inUpdateQuery.FromItems/DeleteQuery.UsingItemsinstead of the embeddedclause.TableRefon the query struct. Eachum.From(...)ordm.Using(...)appends one comma-separatedfrom_item(last call no longer wins). Useum.Table(...)/dm.From(...)for the update/delete target table. (thanks @atzedus) - BREAKING: PostgreSQL
sm.FromFunctionandum.FromFunctionno longer returnFromChainor applyFROM/USINGby themselves. They returnbob.Expressionand must be passed tosm.From(...)/um.From(...)/dm.Using(...)— e.g.sm.From(sm.FromFunction(psql.F("generate_series", 1, 3)()))instead ofsm.FromFunction(...). Aliasing and other table modifiers belong onsm.From(...)/um.From(...). (thanks @atzedus) - BREAKING: PostgreSQL
sm.From/FromChainforSelectQuerynow set theFROMsource viaAppendTableRef(replace semantics) instead ofSetTable/SetTableAliason afromableinterface. (thanks @atzedus) - BREAKING: PostgreSQL
um/dmjoin helpers (InnerJoin,LeftJoin,CrossJoin, etc.) returnJoinChain[*UpdateQuery]/JoinChain[*DeleteQuery]. Use them inum.From(table, joins...)/dm.Using(table, joins...), or as standalone mods afterum.From/dm.Using—AppendJointhen attaches to the lastFromItems/UsingItemsentry. (thanks @atzedus) - BREAKING: PostgreSQL psql join chain modifiers
.Natural(),.On(),.OnEQ(),.Using(), and.UsingAs()now returnJoinChainfor fluent chaining instead ofbob.Mod. (thanks @atzedus)
Fixed
- Fix PostgreSQL
sm.Fromreplacing a previousFROMwithout clearing a stale table alias when the new source has no alias. (thanks @atzedus) - Fix PostgreSQL
sm.With(...).SearchBreadth(...)renderingSEARCH DEPTHinstead ofSEARCH BREADTHin 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 usingtype_system: "database/sql"anduuid_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)
- Added PostgreSQL
-
v0.43.1-0.20260515161103-b81c763b87df15 May 2026 pre-releaseNothing published for this version
-
v0.43.1-0.20260513003548-f4795cd9f32b13 May 2026 pre-releaseNothing published for this version
-
v0.43.1-0.20260508142052-4adc5449dce208 May 2026 pre-releaseNothing published for this version
-
v0.43.1-0.20260506224915-316333a7411b06 May 2026 pre-releaseNothing published for this version
-
v0.43.1-0.20260505062107-b4f99edf899c05 May 2026 pre-releaseNothing published for this version
-
v0.43.029 Apr 2026Release notes
Open source →Added
- Added PostgreSQL
MERGEstatement support with full syntax including:MERGE INTO ... USING ... ON ...with table aliases andONLYmodifierWHEN MATCHED,WHEN NOT MATCHED,WHEN NOT MATCHED BY SOURCEclausesUPDATE,INSERT,DELETE,DO NOTHINGactions- Support for
AND conditionin WHEN clauses OVERRIDING SYSTEM VALUEandOVERRIDING USER VALUEfor INSERT actionsRETURNINGclause support (PostgreSQL 17+) (thanks @atzedus)- Note: the SQL parser used for sql-to-code generation does not yet support
MERGEstatements
- Added
psql.SetVersion,psql.GetVersion, andpsql.VersionAtLeastfunctions for context-based PostgreSQL version management (thanks @atzedus) - Added
Table.Merge()method for ORM-style MERGE operations with automaticRETURNING *for PostgreSQL 17+ (thanks @atzedus) - Added
mmpackage with modifiers for building MERGE queries (mm.Into,mm.Using,mm.WhenMatched,mm.WhenNotMatched,mm.WhenNotMatchedBySource, etc.) (thanks @atzedus) - Added
enum_formatconfiguration 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
PreloadCountandThenLoadCountto 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.Eachfunction to iterate over query results (range-over-func). (thanks @toqueteos) - Added support for the
VALUESstatement in MySQL, PostgreSQL, and SQLite. (thanks @manhrev) - Added MariaDB compatibility check in gen/bobgen-mysql (thanks @dumdev25)
- Added
ALL,SOME,ANYexpressions for MySQL and PostgreSQL dialects. AddedEXISTSexpression for all dialects. (thanks @manhrev) - Added a customizable MySQL and PostgreSQL driver image setting for
bobgen-sql. (thanks @manhrev)
Fixed
- Fix
pgxdriverCommit()returningnilinstead ofpgx.ErrTxClosedwhen 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 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
RandIntwithNextUniqueInt(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()usingSELECT *instead of explicit model columns when re-fetching inserted rows, consistent with PostgreSQL/SQLiteRETURNING. (thanks @tak848)
New Contributors
- @olafal0 made their first contribution in #596
- @toqueteos made their first contribution in #607
- @dumdev25 made their first contribution in #614
- @manhrev made their first contribution in #613
- @Xaeroxe made their first contribution in #615
- @aronsx made their first contribution in #630
- @fisayoafolayan made their first contribution in #644
- @Ocyss made their first contribution in #646
- @wucm667 made their first contribution in #661
Full Changelog: v0.42.0...v0.43.0
Release notes
Open source →Added
- Added PostgreSQL
MERGEstatement support with full syntax including:MERGE INTO ... USING ... ON ...with table aliases andONLYmodifierWHEN MATCHED,WHEN NOT MATCHED,WHEN NOT MATCHED BY SOURCEclausesUPDATE,INSERT,DELETE,DO NOTHINGactions- Support for
AND conditionin WHEN clauses OVERRIDING SYSTEM VALUEandOVERRIDING USER VALUEfor INSERT actionsRETURNINGclause support (PostgreSQL 17+) (thanks @atzedus)- Note: the SQL parser used for sql-to-code generation does not yet support
MERGEstatements
- Added
psql.SetVersion,psql.GetVersion, andpsql.VersionAtLeastfunctions for context-based PostgreSQL version management (thanks @atzedus) - Added
Table.Merge()method for ORM-style MERGE operations with automaticRETURNING *for PostgreSQL 17+ (thanks @atzedus) - Added
mmpackage with modifiers for building MERGE queries (mm.Into,mm.Using,mm.WhenMatched,mm.WhenNotMatched,mm.WhenNotMatchedBySource, etc.) (thanks @atzedus) - Added
enum_formatconfiguration 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
PreloadCountandThenLoadCountto 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.Eachfunction to iterate over query results (range-over-func). (thanks @toqueteos) - Added support for the
VALUESstatement in MySQL, PostgreSQL, and SQLite. (thanks @manhrev) - Added MariaDB compatibility check in gen/bobgen-mysql (thanks @dumdev25)
- Added
ALL,SOME,ANYexpressions for MySQL and PostgreSQL dialects. AddedEXISTSexpression 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
pgxdriverCommit()returningnilinstead ofpgx.ErrTxClosedwhen 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
FromExistingmethods 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
RandIntwithNextUniqueInt(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()usingSELECT *instead of explicit model columns when re-fetching inserted rows, consistent with PostgreSQL/SQLiteRETURNING. (thanks @tak848)
- Added PostgreSQL
-
v0.42.1-0.20260425214547-febd197867b325 Apr 2026 pre-releaseNothing published for this version
-
v0.42.1-0.20260414223129-e84c7f4903c114 Apr 2026 pre-releaseNothing published for this version
-
v0.42.1-0.20260411215148-c4319ea563dd11 Apr 2026 pre-releaseNothing published for this version
-
v0.42.1-0.20260405025056-50353154d23905 Apr 2026 pre-releaseNothing published for this version
-
v0.42.1-0.20260311201022-d4f6947b4a2611 Mar 2026 pre-releaseNothing published for this version
-
v0.42.1-0.20260305085859-d9c40b0abedd05 Mar 2026 pre-releaseNothing published for this version
-
v0.42.1-0.20260220013441-4d86d6fb6efb20 Feb 2026 pre-releaseNothing published for this version
-
v0.42.1-0.20260206110159-054d6b9081cd06 Feb 2026 pre-releaseNothing published for this version
-
v0.42.1-0.20260124111142-e9f80988065924 Jan 2026 pre-releaseNothing published for this version
-
v0.42.1-0.20260111231722-1ab321a734f111 Jan 2026 pre-releaseNothing published for this version
-
v0.42.1-0.20260105094834-4f81249fd9a805 Jan 2026 pre-releaseNothing published for this version
-
v0.42.025 Nov 2025Release notes
Open source →Fixed
- Fixed a bug where the generated loaders for many-to-many relationships were skipping related rows. (thanks @TylerJGabb)
Added
- Include
shell.nixfor developers using Nix to create development environments. (thanks @EliRibble) - Additional README content on how developers can use linting and unit testing to contribute. (thanks @EliRibble)
- Added
Plusexpression chain method (thanks @atzedus).
Changed
- Export
orm.NullTypeConverter. (thanks @Serjlee) - Uses
io.StringWriterinstead ofio.Writerfor efficiency since we are always writing strings.
New Contributors
- @EliRibble made their first contribution in #575
- @atzedus made their first contribution in #583
- @TylerJGabb made their first contribution in #586
- @Serjlee made their first contribution in #591
Full Changelog: v0.41.1...v0.42.0
Release notes
Open source →Fixed
- Fixed a bug where the generated loaders for many-to-many relationships were skipping related rows. (thanks @TylerJGabb)
Added
- Include
shell.nixfor developers using Nix to create development environments. (thanks @EliRibble) - Additional README content on how developers can use linting and unit testing to contribute. (thanks @EliRibble)
- Added
Plusexpression chain method (thanks @atzedus).
Changed
- Export
orm.NullTypeConverter. (thanks @Serjlee) - Uses
io.StringWriterinstead ofio.Writerfor efficiency since we are always writing strings.
-
v0.41.2-0.20251016212905-96da65fd88a516 Oct 2025 pre-releaseNothing published for this version
-
v0.41.102 Sep 2025Release notes
Open source →Fixed
- Properly handle code generation tests for compound queries in MySQL.
Full Changelog: v0.41.0...v0.41.1
Release notes
Open source →Fixed
- Properly handle code generation tests for compound queries in MySQL.
-
v0.41.002 Sep 2025Release notes
Open source →Added
drivers/pgx.Poolnow includes the methodsAcquireandAcquireFuncwhich mirror the methods inpgx/v5/pgxpoolto acquire a connection from the pool (thanks @Eyal-Shalev).- Added the
drivers/pgx.PoolConntype which is a wrapper aroundpgx/v5/pgxpool.Conn.
Changed
- Use the full column type and not just the datatype as the
DBTypein bobgen-mysql. bob.Transactoris 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
int64and all floating point types are mapped tofloat64.
Fixed
- Fixed an issue where
bobgen-mysqlcould not detect unsigned integer columns in queries. - Properly close
pgxtransactions if the context used inBeginTxis cancelled. - Fix issues with generating code for relationships defined with
WhereExpr. - Support
uint64type when scanning columns astypes.Uint64. This fixes scanningBIGINT UNSIGNEDMySQL columns astypes.Uint64wheninterpolateParamsis 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.3-0.20250828221845-a864228459c728 Aug 2025 pre-releaseNothing published for this version
-
v0.40.3-0.20250819175115-2ca61849c6db19 Aug 2025 pre-releaseNothing published for this version
-
v0.40.216 Aug 2025Release notes
Open source →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
CompareExprwith 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.114 Aug 2025 -
v0.40.013 Aug 2025 withdrawnVersion retracted: Fatal bug in preloading relationships with `models.Preload.<Table>.<Relationship>()`
Release notes
Open source →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 onenums.factory: Generates code for factories. Depends onmodels.dberrors: Generates code for unique constraint errors. Depends onmodels.where: Generates type-safe code forWHEREclauses in queries. Depends onmodels.loaders: Adds templates to themodelspackage to generate code for loaders e.gmodels.SelectThenLoad.Table.Rel().joins: Adds templates to themodelspackage to generate code for joins e.gmodels.SelectJoin.Table.LeftJoin.Rel.queries: Generates code for queries.
- Added new
types.Uint64type that sends values to the database as strings. This is necessary because usinguint64directly can cause an overflow if the value exceeds the maximum value of anint64. This is a limitation imposed bydatabase/sql/driver.Valuerinterface. - Added support for
pgvectortypes during code generation.pgvector.Vectorpgvector.HalfVectorpgvector.SparseVector
Changed
- Enums are now imported directly from a new generated
enumspackage. This makes it easier to use enums in other packages without having to depend on themodelspackage. - Preload functions now take a custom
orm.PreloadRelstruct instead of reusingorm.Relationship. - By default, factories are now generated in
./factoryinstead 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
dberrorspackage instead of being generated in themodelspackage. - Tests in the generated
modelspackage are no longer generated in a separatemodels_testpackage. There is no longer any circular dependency since tests for the unique constraint errors are generated in thedberrorspackage. orm.Columnshas been moved toexpr.ColumnsExpr.orm.NewColumnshas been moved toexpr.NewColumnsExpr.<Table>.Columns()is removed. The columns expression is now expected to be embedded in theColumnsfield of the<Table>struct.<dialect>.Viewand<dialect>.Tablenow take an additional type parameter for the columns type. This is assigned to theColumnsfield withNewView/NewTablefunctions.
Removed
- Removed the
no_factoryconfiguration option. It is now replaced with thefactoryplugin which can be enabled or disabled. See https://bob.stephenafamo.com/docs/code-generation/configuration#plugins-configuration for more details. - Removed the
OnlyandExceptexported functions inorm. They are now in the privateinternalpackage. - Removed the generated
models.<Model>Columnsglobal variable. It can now be accessed throughmodels.<Table>.Columns. - Removed the generated
models.TableNamesandmodels.ColumnNamesglobal variables. Their use can be replaced with thedbinfoplugin which generates adbinfopackage 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
UPDATEqueries that do not contain aFROMclause. - 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
- Made code generation modular by relying on built-in plugins that can be enabled or disabled in the configuration.
-
v0.39.1-0.20250811103155-d917f36e302511 Aug 2025 pre-releaseNothing published for this version
-
v0.39.1-0.20250810215143-ea7a9b5c289f10 Aug 2025 pre-releaseNothing published for this version
-
v0.39.1-0.20250809232409-cffc0a4b196409 Aug 2025 pre-releaseNothing published for this version
-
v0.39.1-0.20250808135140-13ab15de2a1f08 Aug 2025 pre-releaseNothing published for this version
-
v0.39.1-0.20250807162141-1a6196ec470507 Aug 2025 pre-releaseNothing published for this version
-
v0.39.1-0.20250806235548-c893d7d53f5e06 Aug 2025 pre-releaseNothing published for this version
-
v0.39.1-0.20250804093216-b2e9e2d2da4304 Aug 2025 pre-releaseNothing published for this version
-
v0.39.1-0.20250804092313-111b290e348a04 Aug 2025 pre-releaseNothing published for this version
-
v0.39.1-0.20250731141400-45b4436fceba31 Jul 2025 pre-releaseNothing published for this version
-
v0.39.028 Jul 2025Release notes
Open source →Added
- Added the
Asmethod toclause.TableRef, which sets the alias and return a copy of the struct. (thanks @Nitjsefni7) - Added the
type_systemconfiguration option to determine how to generate null and optional values in the generated code. Possible options:github.com/aarondl/opt,github.com/aarondl/opt/nullordatabase/sql. The default value isgithub.com/aarondl/opt. - When generating code for queries, The
Allmethod of the generated query will return a struct with nested fields instead of a flat struct.- columns with dots (
.) are assumed to be ato-manynested field. - columns with double underscores (
__) are assumed to be ato-onenested field.
- columns with dots (
- Implement
--prefixannotation in queries forbobgen-psql. - Add FromExistingRel method to factories to create a template from an existing model. (thanks @dutow)
- Add WithExistingRel 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
Modis now a separate field inorm.ModQueryandorm.ModExecQuery.Allxnow takes aTransformertype 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
NewXWithContextthat accepts a context in addition toNewXthat does not. This provides a cleaner API for the callers, while still allowing the use of context internally. (thanks @abdusco)
Removed
- Removed the
fallback_nullconfiguration option. It is now replaced with thetype_systemconfiguration 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,timestampandtimestamptztypes inbobgen-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
autoincrproperty 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)
- Added the
-
v0.38.1-0.20250724174351-dd16525bdd3b24 Jul 2025 pre-releaseNothing published for this version
-
v0.38.1-0.20250722094724-08202428a12022 Jul 2025 pre-releaseNothing published for this version
-
v0.38.1-0.20250720193027-2f1f83bba3c120 Jul 2025 pre-releaseNothing published for this version
-
v0.38.1-0.20250720171859-5552e5def95420 Jul 2025 pre-releaseNothing published for this version