<commit_before>require 'bigdecimal'
require 'date'

module Arel
  module Visitors
    class ToSql < Arel::Visitors::Visitor
      def initialize engine
        @engine         = engine
        @connection     = nil
        @last_column    = nil
        @quoted_tables  = {}
        @quoted_columns = {}
        @column_cache   = Hash.new { |h,conn|
          h[conn] = Hash.new { |conn_h,column|
            conn_h[column] = {}
          }
        }
        @table_exists   = Hash.new { |h,conn|
          h[conn] = {}
        }
      end

      def accept object
        @last_column = nil
        @engine.connection_pool.with_connection do |conn|
          @connection = conn
          super
        end
      end

      private
      def visit_Arel_Nodes_DeleteStatement o
        [
          "DELETE FROM #{visit o.relation}",
          ("WHERE #{o.wheres.map { |x| visit x }.join ' AND '}" unless o.wheres.empty?)
        ].compact.join ' '
      end

      def visit_Arel_Nodes_UpdateStatement o
        if o.orders.empty? && o.limit.nil?
          wheres = o.wheres
        else
          stmt             = Nodes::SelectStatement.new
          core             = stmt.cores.first
          core.froms       = o.relation
          core.projections = [o.relation.primary_key]
          stmt.limit       = o.limit
          stmt.orders      = o.orders

          wheres = [Nodes::In.new(o.relation.primary_key, [stmt])]
        end

        [
          "UPDATE #{visit o.relation}",
          ("SET #{o.values.map { |value| visit value }.join ', '}" unless o.values.empty?),
          ("WHERE #{wheres.map { |x| visit x }.join ' AND '}" unless wheres.empty?)
        ].compact.join ' '
      end

      def visit_Arel_Nodes_InsertStatement o
        [
          "INSERT INTO #{visit o.relation}",

          ("(#{o.columns.map { |x|
                quote_column_name x.name
            }.join ', '})" unless o.columns.empty?),

          (visit o.values if o.values),
        ].compact.join ' '
      end

      def visit_Arel_Nodes_Exists o
        "EXISTS (#{visit o.expressions})#{
          o.alias ? " AS #{visit o.alias}" : ''}"
      end

      def table_exists? name
        return true if table_exists.key? name

        @connection.tables.each do |table|
          table_exists[table] = true
        end

        table_exists.key? name
      end

      def table_exists
        @table_exists[@connection]
      end

      def column_for attr
        name    = attr.name.to_sym
        table   = attr.relation.name

        return nil unless table_exists? table

        # If we don't have this column cached, get a list of columns and
        # cache them for this table
        unless column_cache.key? table
          columns = @connection.columns(table, "#{table}(#{name}) Columns")
          column_cache[table] = Hash[columns.map { |c| [c.name.to_sym, c] }]
        end

        column_cache[table][name]
      end

      def column_cache
        @column_cache[@connection]
      end

      def visit_Arel_Nodes_Values o
        "VALUES (#{o.expressions.zip(o.columns).map { |value, attr|
          quote(value, attr && column_for(attr))
        }.join ', '})"
      end

      def visit_Arel_Nodes_SelectStatement o
        [
          o.cores.map { |x| visit_Arel_Nodes_SelectCore x }.join,
          ("ORDER BY #{o.orders.map { |x| visit x }.join(', ')}" unless o.orders.empty?),
          ("LIMIT #{visit o.limit}" if o.limit),
          (visit(o.offset) if o.offset),
          (visit(o.lock) if o.lock),
        ].compact.join ' '
      end

      def visit_Arel_Nodes_SelectCore o
        [
          "SELECT #{o.projections.map { |x| visit x }.join ', '}",
          visit(o.source),
          ("WHERE #{o.wheres.map { |x| visit x }.join ' AND ' }" unless o.wheres.empty?),
          ("GROUP BY #{o.groups.map { |x| visit x }.join ', ' }" unless o.groups.empty?),
          (visit(o.having) if o.having),
        ].compact.join ' '
      end

      def visit_Arel_Nodes_Having o
        "HAVING #{visit o.expr}"<commit_msg>make our caching per connection pool, not per connection<commit_after>require 'bigdecimal'
require 'date'

module Arel
  module Visitors
    class ToSql < Arel::Visitors::Visitor
      def initialize engine
        @engine         = engine
        @connection     = nil
        @pool           = nil
        @last_column    = nil
        @quoted_tables  = {}
        @quoted_columns = {}
        @column_cache   = Hash.new { |h,pool|
          h[pool] = Hash.new { |conn_h,column|
            conn_h[column] = {}
          }
        }
        @table_exists   = Hash.new { |h,pool|
          h[pool] = {}
        }
      end

      def accept object
        @last_column = nil
        @pool        = @engine.connection_pool
        @pool.with_connection do |conn|
          @connection = conn
          super
        end
      end

      private
      def visit_Arel_Nodes_DeleteStatement o
        [
          "DELETE FROM #{visit o.relation}",
          ("WHERE #{o.wheres.map { |x| visit x }.join ' AND '}" unless o.wheres.empty?)
        ].compact.join ' '
      end

      def visit_Arel_Nodes_UpdateStatement o
        if o.orders.empty? && o.limit.nil?
          wheres = o.wheres
        else
          stmt             = Nodes::SelectStatement.new
          core             = stmt.cores.first
          core.froms       = o.relation
          core.projections = [o.relation.primary_key]
          stmt.limit       = o.limit
          stmt.orders      = o.orders

          wheres = [Nodes::In.new(o.relation.primary_key, [stmt])]
        end

        [
          "UPDATE #{visit o.relation}",
          ("SET #{o.values.map { |value| visit value }.join ', '}" unless o.values.empty?),
          ("WHERE #{wheres.map { |x| visit x }.join ' AND '}" unless wheres.empty?)
        ].compact.join ' '
      end

      def visit_Arel_Nodes_InsertStatement o
        [
          "INSERT INTO #{visit o.relation}",

          ("(#{o.columns.map { |x|
                quote_column_name x.name
            }.join ', '})" unless o.columns.empty?),

          (visit o.values if o.values),
        ].compact.join ' '
      end

      def visit_Arel_Nodes_Exists o
        "EXISTS (#{visit o.expressions})#{
          o.alias ? " AS #{visit o.alias}" : ''}"
      end

      def table_exists? name
        return true if table_exists.key? name

        @connection.tables.each do |table|
          table_exists[table] = true
        end

        table_exists.key? name
      end

      def table_exists
        @table_exists[@pool]
      end

      def column_for attr
        name    = attr.name.to_sym
        table   = attr.relation.name

        return nil unless table_exists? table

        # If we don't have this column cached, get a list of columns and
        # cache them for this table
        unless column_cache.key? table
          columns = @connection.columns(table, "#{table}(#{name}) Columns")
          column_cache[table] = Hash[columns.map { |c| [c.name.to_sym, c] }]
        end

        column_cache[table][name]
      end

      def column_cache
        @column_cache[@pool]
      end

      def visit_Arel_Nodes_Values o
        "VALUES (#{o.expressions.zip(o.columns).map { |value, attr|
          quote(value, attr && column_for(attr))
        }.join ', '})"
      end

      def visit_Arel_Nodes_SelectStatement o
        [
          o.cores.map { |x| visit_Arel_Nodes_SelectCore x }.join,
          ("ORDER BY #{o.orders.map { |x| visit x }.join(', ')}" unless o.orders.empty?),
          ("LIMIT #{visit o.limit}" if o.limit),
          (visit(o.offset) if o.offset),
          (visit(o.lock) if o.lock),
        ].compact.join ' '
      end

      def visit_Arel_Nodes_SelectCore o
        [
          "SELECT #{o.projections.map { |x| visit x }.join ', '}",
          visit(o.source),
          ("WHERE #{o.wheres.map { |x| visit x }.join ' AND ' }" unless o.wheres.empty?),
          ("GROUP BY #{o.groups.map { |x| visit x }.join ', ' }" unless o.groups.empty?),
          (visit(o.having) if o.having),
        ].compact.join ' '
      end

      def visit_Arel_Nodes_Having o
        "HAVING #{visit o.expr}"
{'fraction_non_alphanumeric': 0.123046875, 'fraction_numerical': 0.0, 'mean_word_length': 1.6844692005242463, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5274859', 'n_tokens_mistral': 2590, 'n_tokens_neox': 2494, 'n_words': 601}