On Wednesday, October 10, 2018 at 11:06:11 AM UTC-7, Mike Pastore wrote:
>
> On Friday, October 5, 2018 at 6:51:21 PM UTC-5, Jeremy Evans wrote:
>>
>> I've no doubt that what you are describing is happening, but a simple 
>> example does not reproduce:
>>
>
> Alright, I seem to have hit some kind of a nightmarish edge case here. 
> Bear with me and I'll try to lay it out as clearly as possible. The problem 
> only occurs under these conditions:
>
>    - A (uniqueness?) validation is added to the :order_number field 
>    (tested with both the :constraint_validations and :validation_helpers 
>    plugins) on the model, regardless of the values of :allow_nil and/or 
>    :allow_missing and whether or not there is actually a unique constraint on 
>    the column.
>    - The :defaults_setter plugin is loaded globally or on the model with 
>    :cache=>true.
>
> This combination of plugins and settings causes :order_number to take a 
> nil value on Model#create and fail the identity column's NOT NULL 
> constraint. The validation also breaks the 
> Sequel.lit('DEFAULT') workaround, whether it's specified at Model#create 
> time or as a default value. It gives me the following error:
>
> /Users/mwp/.rbenv/versions/2.5.1/lib/ruby/gems/2.5.0/gems/sequel-5.13.0/
> lib/sequel/adapters/postgres.rb:152:in `async_exec': PG::SyntaxError: 
> ERROR:  DEFAULT is not allowed in this context (Sequel::DatabaseError)
> LINE 1: ...t(*) AS "count" FROM "bs" WHERE ("order_number" = DEFAULT) L...
>
> Which makes sense. Let me know if you want the full backtrace. 
>
> I can't even begin to image what a fix for this would look like and let me 
> just state up-front that my expectations of this being fixed are low. In a 
> perfect world, I would like to add a unique constraint and validation to 
> this column in my migration (validate { unique :order_number }) and have 
> it work as expected with the :constraint_validations and :default_setters 
> plugins with :cache=>true. In the meantime, I have identified the following 
> alternatives:
>
>    - Disable the :default_setters cache on this particular model
>    - Add a unique constraint but no validation to the :order_number 
>    column (and handle the constraint violation exception in my application 
>    framework)
>
> Here's the full repro (which is very close to your original):
>
> DB.create_table(:bs) do
>   primary_key :id
>   Integer :order_number, :identity=>true
>   Integer :n
> end
>
> class B < Sequel::Model
>   plugin :defaults_setter, :cache=>true
>   plugin :validation_helpers
>
>   def validate
>     super
>     validates_unique :order_number, :allow_missing=>true
>   end
> end
>
> B.create(:n=>1)
>
> Thanks Jeremy! 
>
> P.S. If you don't already know, it is possible to insert duplicate values 
> for identity columns that are GENERATED BY DEFAULT (vs. GENERATED ALWAYS), 
> thus the need for a unique constraint and/or validation.
>

The simplest solution is just to get the sequence number before inserting:

   def before_create
    super
    self.order_number = DB.get{nextval("bs_order_number_seq")}
  end

If that won't work for you, please let me know and I can see about how to 
exclude the column from being used in the INSERT statement.

Thanks,
Jeremy

-- 
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 post to this group, send email to [email protected].
Visit this group at https://groups.google.com/group/sequel-talk.
For more options, visit https://groups.google.com/d/optout.

Reply via email to