Skip to content

Instantly share code, notes, and snippets.

@hellojustin
Created January 23, 2025 11:01
Show Gist options
  • Save hellojustin/d43e9f52f2ad2a3559e313d406ea56c1 to your computer and use it in GitHub Desktop.
Save hellojustin/d43e9f52f2ad2a3559e313d406ea56c1 to your computer and use it in GitHub Desktop.
Reading from a Temp Table that is Dropped on Commit
# frozen_string_literal: true
# Temp Table Read Example
#
# Demonstrating how data can be read from a temp table
# that is nomrally dropped when a transaction is committed,
# without altering the transaction.
#
# cp <this file> <rails project root>
# cd <rails project w/ db>
# bundle exec rails runner temp_table_read_examples.rb
#
module Helpers
def create_temp_table
ActiveRecord::Base.connection.execute <<~SQL.squish
create temp table my_temp (
name varchar,
number bigint
)
on commit drop
SQL
end
def insert_into_temp_table
ActiveRecord::Base.connection.execute "insert into my_temp values ('Bruce Springsteen', 1)"
end
def read_from_temp_table
ActiveRecord::Base.connection.execute "select * from my_temp"
end
def temp_table_exists?
ActiveRecord::Base.connection.execute "select * from my_temp"
true
rescue ActiveRecord::StatementInvalid
false
end
def create_and_insert
create_temp_table
insert_into_temp_table
end
def create_and_insert_in_transaction
ActiveRecord::Base.transaction do
create_and_insert
end
end
end
module Examples
include Helpers
def read_attempt_after_transaction
create_and_insert_in_transaction
read_from_temp_table ## -- should fail.
end
def read_with_outer_transaction
result = nil
ActiveRecord::Base.transaction do
create_and_insert_in_transaction
result = read_from_temp_table ## -- should work.
end
result
end
def read_with_outer_transaction_and_rollback
result = nil
ActiveRecord::Base.transaction do
create_and_insert_in_transaction
result = read_from_temp_table ## -- should work.
raise ActiveRecord::Rollback
end
result
end
end
class TempTableShowcase
include Examples
def run
puts "EXAMPLE 1: Reading from temp table after transaction should fail."
begin
read_attempt_after_transaction
rescue ActiveRecord::StatementInvalid => e
puts "-- Assertion 1 Success: received ActiveRecord::StatementInvalid as expected"
puts "-- because table was dropped when transaction was committed."
puts "-- #{e.message}"
end
puts "\nEXAMPLE 2: Reading from temp table within outer transaction should succeed."
result = read_with_outer_transaction
puts "-- Assertion 1 Success: received #{result.to_a.inspect} as expected" if result
if temp_table_exists?
puts "-- Assertion 2 Failed: temp table was NOT dropped when outer transaction was committed."
else
puts "-- Assertion 2 Success: temp table was dropped as expected."
end
puts "\nEXAMPLE 3: Reading from temp table within outer transaction that is rolled back should succeed."
result = read_with_outer_transaction_and_rollback
puts "-- Assertion 1 Success: received #{result.to_a.inspect} as expected" if result
if temp_table_exists?
puts "-- Assertion 2 Failed: temp table was NOT dropped when outer transaction was rolled back."
else
puts "-- Assertion 2 Success: temp table was dropped as expected."
end
end
end
TempTableShowcase.new.run
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment