The Postgres primary_key_sequence method caches the results of the sequence
lookup. If an unqualified table name is passed in it will store the
unqualified table name as the cache lookup key with the schema qualified
sequence as the value. If the search_path is changed to a different schema
and the primary_key_sequence method called again with an unqualified table
name it will return the sequence name qualified with the previous schema.
Is this a bug or maybe I am misusing the method?
Here is a script to illustrate the issue:
# frozen_string_literal: true
require "bundler"
Bundler.setup
require "sequel"
require "uri"
require "cgi"
uri = URI.parse(ENV["DATABASE_URL"])
username, password, host, port, name = [uri.user && CGI.unescape(uri.user),
uri.password && CGI.unescape(uri.password), uri.host, uri.port,
uri.path[1..-1]]
name = "sequence_test"
puts "Resetting database #{name} (#{host}:#{port})"
system "dropdb -h #{host} -p #{port} -U #{username || "postgres"} #{name}"
system "createdb -h #{host} -p #{port} -U #{username || "postgres"} #{name}
--encoding=UTF8 --locale=en_US.UTF8 --template=template0"
DB = Sequel.connect
"postgres://#{username}:#{password}@#{host}:#{port}/#{name}"
Sequel.extension :migration
Sequel.migration do
up do
%i( foo bar ).each do |schema|
self << "CREATE SCHEMA #{schema}"
self << "SET search_path TO #{schema};"
create_table :albums do
primary_key :id
end
end
end
end.apply DB, :up
class Album < Sequel::Model
end
DB << "SET search_path TO foo, public;"
10.times do |i|
Album.create
end
%i( foo bar ).each do |schema|
puts ""
DB << "SET search_path TO #{schema}, public;"
puts "search_path: #{DB["show search_path;"].first[:search_path]}"
album = Album.new
puts "Album.count: #{Album.count}"
puts "Album.order(Sequel.desc(:id)).first.id:
#{Album.order(Sequel.desc(:id)).first&.id.inspect}"
puts "album.class.table_name: #{album.class.table_name}"
puts "DB.primary_key_sequence(album.class.table_name):
#{DB.primary_key_sequence(album.class.table_name)}"
puts "DB.get{ nextval(DB.primary_key_sequence(album.class.table_name)) }
#{DB.get{ nextval(DB.primary_key_sequence(album.class.table_name)) }}"
end
DB.disconnect
%i( bar foo ).each do |schema|
puts ""
DB << "SET search_path TO #{schema}, public;"
puts "search_path: #{DB["show search_path;"].first[:search_path]}"
album = Album.new
puts "Album.count: #{Album.count}"
puts "Album.order(Sequel.desc(:id)).first.id:
#{Album.order(Sequel.desc(:id)).first&.id.inspect}"
puts "album.class.table_name: #{album.class.table_name}"
puts "DB.primary_key_sequence(album.class.table_name):
#{DB.primary_key_sequence(album.class.table_name)}"
puts "DB.get{ nextval(DB.primary_key_sequence(album.class.table_name)) }
#{DB.get{ nextval(DB.primary_key_sequence(album.class.table_name)) }}"
end
In my own app I overwrote the method to always use the schema qualified
table name as the cache key and to automatically qualify the passed in
table name if there is only one schema in the search_path however I am not
sure what all this method is used for internally and why it is cached so I
am hesitant to change it in case the caching is very important.
--
You received this message because you are subscribed to the Google Groups
"sequel-talk" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
To view this discussion on the web visit
https://groups.google.com/d/msgid/sequel-talk/7305153c-6c34-4a52-864d-ef3e31c75a6do%40googlegroups.com.