instacart / makara

A Read-Write Proxy for Connections; Also provides an ActiveRecord adapter.

Home Page:http://tech.taskrabbit.com/

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Choosing Primary instead of Replica when using 'with' (because of newlines)

jackcb123 opened this issue · comments

Issue: Many of my complex sql statements were being performed by the primary instead of the replica. It turns out that the sql_replica_matchers regex is insufficient for queries that begin with CTE 'with' statements.

In lib/active_record/connection_adapters/makara_abstract_adapter.rb

SQL_REPLICA_MATCHERS = [/\A\s*(select|with.+\)\s*select)\s/i].map(&:freeze).freeze

should be changed to

SQL_REPLICA_MATCHERS = [/\A\s*(select|with[\s\S]*\)\s*select)\s/i].map(&:freeze).freeze

[\s\S] is the difference and accounts for new lines.

This is because '.' regex doesn't account for new lines (which will obviously be there in complex sql statements).

My workaround is this. Hope this helps! :)

class ActiveRecord::ConnectionAdapters::MakaraAbstractAdapter < ::Makara::Proxy
  CUSTOM_SQL_REPLICA_MATCHERS = [/\A\s*(select|with[\s\S]*\)\s*select)\s/i].map(&:freeze).freeze

  def sql_slave_matchers
    CUSTOM_SQL_REPLICA_MATCHERS
  end

  def sql_replica_matchers
    CUSTOM_SQL_REPLICA_MATCHERS
  end
end