makara icon indicating copy to clipboard operation
makara copied to clipboard

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

Open jackcb123 opened this issue 1 year ago • 0 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

jackcb123 avatar Aug 17 '23 17:08 jackcb123