uptrace / bun

SQL-first Golang ORM
https://bun.uptrace.dev
BSD 2-Clause "Simplified" License
3.83k stars 230 forks source link

Default values being ignored on NewInsert? #1045

Open fhendrikx opened 3 weeks ago

fhendrikx commented 3 weeks ago

Hi,

I'm new to Bun, hopefully you can put me right.

When inserting a record using NewInsert(), it seems to ignore my request to use the default value.

For example, the model contains a "State" integer:

 State  int  `bun:",nullzero,notnull,default:4"`

But when creating the record and then inserting it:

        users := []*User{
                {Username: "test 1", Name: "testing"},
                {Username: "test 2", Name: "testing"},
        }

        db.NewInsert().Model(&users).Exec(ctx)

The database complains:

pgdriver.Error: ERROR: null value in column "state" of relation "users" violates not-null constraint (SQLSTATE=23502)

Thanks

j2gg0s commented 3 weeks ago

It should work.

Could you provide a reproducible example?

fhendrikx commented 3 weeks ago

I will do that shortly.

fhendrikx commented 3 weeks ago

I've attached a sample that reproduces the issue. It looks like the issue occurs on fields that don't have a default set in the database.

So, in this example, the field "state" has a default set in the database, but field "testint" doesn't... and the code fails. If I alter the table definition to include a default, then it all works.

Table definition:

                        Table "public.blob"
 Column  |          Type          | Collation | Nullable | Default
---------+------------------------+-----------+----------+---------
 id            | bigint                  |             |                    |
 name      | char varying(150)  |         |                   |
 state      | integer                |             | not null      | 4
 testint    | smallint              |              | not null      |

I don't know if this is the desired behaviour, but seems odd to have to specify a "default" value in the bun model for stuff the database will do anyway... and I was assuming that a bun model definition for default would override the db definition..?

main.txt

j2gg0s commented 3 weeks ago
  1. pgdialect will enable DeafultPlaceholder https://github.com/uptrace/bun/blob/master/dialect/pgdialect/dialect.go#L39
  2. In that case, bun will use DEFAULT AS default https://github.com/uptrace/bun/blob/master/query_insert.go#L337

I think Bun does this assuming that your table structure matches the definition of your struct. If that’s not the case, you can manually disable DefaultPlaceholder and use Go’s default values instead.

fhendrikx commented 3 weeks ago

Thanks for your response, can you please explain how I can enable/disable a feature flag in the dialect?

j2gg0s commented 3 weeks ago

Thanks for your response, can you please explain how I can enable/disable a feature flag in the dialect?

@fhendrikx I’m sorry, but pgdialect currently does not allow you to modify the feature. You may have to resort to copying the code from pgdialect.New into a new function and removing the corresponding feature.

@VladimirStepanov v Is my understanding correct? Is there a specific reason for doing it this way? Could we add an interface to the dialect to remove/disable features?

fhendrikx commented 3 weeks ago

Ah, that explains it. It might be worth adding the ability to toggle the feature flags in some way?