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.

Reply via email to