diff --git a/desc/argument.go b/desc/argument.go index 5d92643..7f7b325 100644 --- a/desc/argument.go +++ b/desc/argument.go @@ -3,6 +3,8 @@ package desc import ( "fmt" "reflect" + + "github.com/jackc/pgx/v5/pgtype/zeronull" ) // Argument represents a single argument for a database query @@ -69,6 +71,7 @@ func extractArguments(td *Table, structValue reflect.Value, filter func(columnNa fieldValue := field.Interface() // get the field value as an interface + // If filter passed, respect just the filter. if filter != nil { if !filter(c.Name) { continue @@ -83,7 +86,7 @@ func extractArguments(td *Table, structValue reflect.Value, filter func(columnNa } } - if c.Default != "" && c.Type == UUID && c.PrimaryKey && !c.Nullable { + if c.Default != "" && c.Type == UUID && !c.Nullable && c.PrimaryKey { if isZero(fieldValue) { continue // skip this field if it is a UUID primary key and required and the field value is zero } @@ -117,10 +120,10 @@ func extractArguments(td *Table, structValue reflect.Value, filter func(columnNa } // filterArguments takes a slice of arguments and a filter function and returns a slice of arguments. -func filterArguments(args Arguments, filter func(arg Argument) bool) Arguments { +func filterArguments(args Arguments, filter func(arg *Argument) bool) Arguments { var filtered Arguments for _, arg := range args { - if filter(arg) { + if filter(&arg) { filtered = append(filtered, arg) } } @@ -129,8 +132,19 @@ func filterArguments(args Arguments, filter func(arg Argument) bool) Arguments { // FilterArgumentsForInsert takes a slice of arguments and returns a slice of arguments for insert. func filterArgumentsForFullUpdate(args Arguments) Arguments { - return filterArguments(args, func(arg Argument) bool { - return !arg.Column.IsGenerated() && !arg.Column.Presenter // && !arg.Column.Unscannable + return filterArguments(args, func(arg *Argument) bool { + c := arg.Column + + if (c.PrimaryKey || c.ReferenceColumnName != "") && c.Default != "" && c.Type == UUID && c.Nullable { + if isZero(arg.Value) { // fixes full update of a record which contains an optional reference UUID, we allow setting it to null, but + // we have to replace empty string with zeronull.UUID{}. Note that on insert we omit it from the query, as it will default to the default sql line default value. + arg.Value = zeronull.UUID{} + } + + return true + } + + return !c.IsGenerated() && !c.Presenter // && !arg.Column.Unscannable }) } diff --git a/go.mod b/go.mod index c32cb7a..deec20b 100644 --- a/go.mod +++ b/go.mod @@ -12,7 +12,7 @@ require ( github.com/jackc/pgpassfile v1.0.0 // indirect github.com/jackc/pgservicefile v0.0.0-20221227161230-091c0ba34f0a // indirect github.com/jackc/puddle/v2 v2.2.1 // indirect - golang.org/x/crypto v0.14.0 // indirect + golang.org/x/crypto v0.15.0 // indirect golang.org/x/sync v0.5.0 // indirect - golang.org/x/text v0.13.0 // indirect + golang.org/x/text v0.14.0 // indirect ) diff --git a/go.sum b/go.sum index 9451410..602ff22 100644 --- a/go.sum +++ b/go.sum @@ -18,14 +18,14 @@ github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UV github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.8.1 h1:w7B6lhMri9wdJUVmEZPGGhZzrYTPvgJArz7wNPgYKsk= github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= -golang.org/x/crypto v0.14.0 h1:wBqGXzWJW6m1XrIKlAH0Hs1JJ7+9KBwnIO8v66Q9cHc= -golang.org/x/crypto v0.14.0/go.mod h1:MVFd36DqK4CsrnJYDkBA3VC4m2GkXAM0PvzMCn4JQf4= +golang.org/x/crypto v0.15.0 h1:frVn1TEaCEaZcn3Tmd7Y2b5KKPaZ+I32Q2OA3kYp5TA= +golang.org/x/crypto v0.15.0/go.mod h1:4ChreQoLWfG3xLDer1WdlH5NdlQ3+mwnQq1YTKY+72g= golang.org/x/mod v0.14.0 h1:dGoOF9QVLYng8IHTm7BAyWqCqSheQ5pYWGhzW00YJr0= golang.org/x/mod v0.14.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= golang.org/x/sync v0.5.0 h1:60k92dhOjHxJkrqnwsfl8KuaHbn/5dl0lUPUklKo3qE= golang.org/x/sync v0.5.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= -golang.org/x/text v0.13.0 h1:ablQoSUd0tRdKxZewP80B+BaqeKJuVhuRxj/dkrun3k= -golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= +golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ= +golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=