Skip to content

Draft: Add code to reproduce BulkInsertSafe error

Igor Frenkel requested to merge test-bulk-insert-safe-timestamps into master

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

Merge request reports