octopus icon indicating copy to clipboard operation
octopus copied to clipboard

saving a relation with using(:slave) causes additional where clauses to multiply

Open knodi opened this issue 7 years ago • 5 comments

If I am in an environment where octopus is enabled, and I save an intermediate relation into a variable that uses using(:shard), then additional calls to that relation will permanently modify it. This won't happen in development mode, where I haven't added "development" to the "environments" array in shards.yml, and it won't happen if I skip the "using(:shard)", and it only happens if I save the relation into an intermediate variable.

This demo is a stripped down example; in reality, I'm saving a base relation and then running it on various created_at ranges, and only the first one gives me correct results.

Demo:

irb(main):022:0> base = User.using(:slave)
=> User(id: integer, login: string, created_at: datetime)
irb(main):035:0> base.where(id: 1).to_sql
=> "SELECT `users`.* FROM `users` WHERE `users`.`id` = 1"
irb(main):036:0> base.where(id: 1).to_sql
=> "SELECT `users`.* FROM `users` WHERE `users`.`id` = 1 AND `users`.`id` = 1"
irb(main):037:0> base.where(id: 1).to_sql
=> "SELECT `users`.* FROM `users` WHERE `users`.`id` = 1 AND `users`.`id` = 1 AND `users`.`id` = 1"
irb(main):038:0> base.where(id: 1).to_sql
=> "SELECT `users`.* FROM `users` WHERE `users`.`id` = 1 AND `users`.`id` = 1 AND `users`.`id` = 1 AND `users`.`id` = 1"

knodi avatar May 05 '17 17:05 knodi

It looks like if the result responds to :all it will modify the scope klass. From what I can tell this was the functionality set way back in 2010 (after change 1435638376a7d203eb34a1cdbc9ebf8a3fe84058), but I'm not sure I understand the motivation for that change.

ScopeProxy.rb

    def method_missing(method, *args, &block)
      result = run_on_shard { @klass.send(method, *args, &block) }
      if result.respond_to?(:all)
        @klass = result
        return self
      end
      result
    end

If you remove the "if" clause from the code the above scenario works. I haven't tried the tests to see what that breaks though ;)

platphorm avatar May 05 '17 22:05 platphorm

Bump - I am observing this in our code as well.

flanger001 avatar Mar 13 '18 14:03 flanger001

@platphorm did you try making that change in production? Are there any side effects you're aware of?

dvandersluis avatar Mar 13 '18 14:03 dvandersluis

@dvandersluis no, we can not afford to publish experimental code to production. we just worked around this issue.

knodi avatar Mar 13 '18 15:03 knodi

@knodi makes sense!

dvandersluis avatar Mar 13 '18 17:03 dvandersluis