Draft: Add code to reproduce BulkInsertSafe error
What does this MR do and why?
This MR adds code to reproduce error when model includes BulkInsertSafe
but doesn't have the common timestamp columns or any other columns not appearing in the unique
part of the query.
Related: #383723 (closed)
How to use this MR
bundle exec rails db:migrate
bundle exec rails c
In console run:
names = ['a', 'b', 'c']
Test::Foo.bulk_upsert!(names.map { |n| Test::Foo.new(name: n, created_at: Time.now, updated_at: Time.now) }, unique_by: %i[name], returns: %i[id name])
Test::Bar.bulk_upsert!(names.map { |n| Test::Bar.new(name: n) }, unique_by: %i[name], returns: %i[id name])
The sql code produced by the 2 calls are as follows:
INSERT INTO "foos" ("name","created_at","updated_at") VALUES ('a', '2023-01-17 22:09:27.133838', '2023-01-17 22:09:27.133840'), ('b', '2023-01-17 22:09:27.134311', '2023-01-17 22:09:27.134311'), ('c', '2023-01-17 22:09:27.134380', '2023-01-17 22:09:27.134381') ON CONFLICT ("name") DO UPDATE SET "updated_at"=excluded."updated_at" RETURNING "id","name" /*application:console,db_config_name:main,console_hostname:ifrenkel-glmbp-m1,console_username:ifrenkel,line:/app/models/concerns/bulk_insert_safe.rb:163
INSERT INTO "bars" ("name") VALUES ('a'), ('b'), ('c') ON CONFLICT ("name") DO NOTHING RETURNING "id","name"
The ActiveRecord::InsertAll
class being used by BulkInsertSafe
will not generate an ON CONFLICT ... UPDATE
clause in the case of Test::Bar
.
Edited by Igor Frenkel