Created
January 23, 2025 11:01
-
-
Save hellojustin/d43e9f52f2ad2a3559e313d406ea56c1 to your computer and use it in GitHub Desktop.
Reading from a Temp Table that is Dropped on Commit
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# 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