<commit_before>require 'active_support/core_ext/array/wrap'
require 'active_support/core_ext/object/blank'

module ActiveRecord
  module QueryMethods
    extend ActiveSupport::Concern

    included do
      (ActiveRecord::Relation::ASSOCIATION_METHODS + ActiveRecord::Relation::MULTI_VALUE_METHODS).each do |query_method|
        attr_accessor :"#{query_method}_values"

        next if [:where, :having, :select].include?(query_method)
        class_eval <<-CEVAL, __FILE__, __LINE__ + 1
          def #{query_method}(*args, &block)
            new_relation = clone
            new_relation.send(:apply_modules, Module.new(&block)) if block_given?
            value = Array.wrap(args.flatten).reject {|x| x.blank? }
            new_relation.#{query_method}_values += value if value.present?
            new_relation
          end
        CEVAL
      end

      class_eval <<-CEVAL, __FILE__, __LINE__ + 1
        def select(*args, &block)
          if block_given?
            to_a.select(&block)
          else
            new_relation = clone
            value = Array.wrap(args.flatten).reject {|x| x.blank? }
            new_relation.select_values += value if value.present?
            new_relation
          end
        end
      CEVAL

      [:where, :having].each do |query_method|
        class_eval <<-CEVAL, __FILE__, __LINE__ + 1
          def #{query_method}(*args, &block)
            new_relation = clone
            new_relation.send(:apply_modules, Module.new(&block)) if block_given?
            value = build_where(*args)
            new_relation.#{query_method}_values += Array.wrap(value) if value.present?
            new_relation
          end
        CEVAL
      end

      ActiveRecord::Relation::SINGLE_VALUE_METHODS.each do |query_method|
        attr_accessor :"#{query_method}_value"

        class_eval <<-CEVAL, __FILE__, __LINE__ + 1
          def #{query_method}(value = true, &block)
            new_relation = clone
            new_relation.send(:apply_modules, Module.new(&block)) if block_given?
            new_relation.#{query_method}_value = value
            new_relation
          end
        CEVAL
      end
    end

    def extending(*modules)
      new_relation = clone
      new_relation.send :apply_modules, *modules
      new_relation
    end

    def lock(locks = true, &block)
      relation = clone
      relation.send(:apply_modules, Module.new(&block)) if block_given?

      case locks
      when String, TrueClass, NilClass
        clone.tap {|new_relation| new_relation.lock_value = locks || true }
      else
        clone.tap {|new_relation| new_relation.lock_value = false }
      end
    end

    def reverse_order
      order_clause = arel.send(:order_clauses).join(', ')
      relation = except(:order)

      if order_clause.present?
        relation.order(reverse_sql_order(order_clause))
      else
        relation.order("#{@klass.table_name}.#{@klass.primary_key} DESC")
      end
    end

    def arel
      @arel ||= build_arel
    end

    def custom_join_sql(*joins)
      arel = table
      joins.each do |join|
        next if join.blank?

        @implicit_readonly = true

        case join
        when Hash, Array, Symbol
          if array_of_strings?(join)
            join_string = join.join(' ')
            arel = arel.join(join_string)
          end
        else
          arel = arel.join(join)
        end
      end
      arel.joins(arel)
    end

    def build_arel
      arel = table

      arel = build_joins(arel, @joins_values) if @joins_values.present?

      @where_values.uniq.each do |where|
        next if where.blank?

        case where
        when Arel::SqlLiteral
          arel = arel.where(where)
        else
          sql = where.is_a?(String) ? where : where.to_sql
          arel = arel.where(Arel::SqlLiteral.new("(#{sql})"))
        end
      end

      arel = arel.having(*@having_values.uniq.select{|h| h.present?})

      arel = arel.take(@limit_value) if @limit_value.present?
      arel = arel.skip(@offset_value) if @offset_value.present?

      arel = arel.group(*@group_values.uniq.select{|g| g.present?})

      arel = arel.order(*@order_values.uniq.select{|o| o.present?}.map(&:to_s))

      selects = @select_values.uniq

      if selects.present?
        selects.each do |s|
          @implicit_readonly = false
          arel = arel.project(s) if s.present?
        end
      else
        arel = arel.project(@klass.quoted_table_name + '.*')
      end

      arel = @from_value.present? ? arel.from(@from_value) : arel.from(@klass.quoted_table_name)

      case @lock_value
      when TrueClass
        arel = arel.lock
      when String
        arel = arel.lock(@lock_value)
      end if @lock_value.present?

      arel
    end

    def build_where(*args)
      return if args.blank?

      opts = args.first
      case opts
      when String, Array
        @klass.send(:sanitize_sql, args.size > 1 ? args : opts)
      when Hash
        attributes = @klass.send(:expand_hash_conditions_for_aggregates, opts)
        PredicateBuilder.new(table.engine).build_from_hash(attributes, table)
      else
        opts
      end
    end

    private

    def build_joins(relation, joins)
      joined_associations = []<commit_msg>Don't waste time building relations if there are no values presents. [#4860 state:resolved]<commit_after>require 'active_support/core_ext/array/wrap'
require 'active_support/core_ext/object/blank'

module ActiveRecord
  module QueryMethods
    extend ActiveSupport::Concern

    included do
      (ActiveRecord::Relation::ASSOCIATION_METHODS + ActiveRecord::Relation::MULTI_VALUE_METHODS).each do |query_method|
        attr_accessor :"#{query_method}_values"

        next if [:where, :having, :select].include?(query_method)
        class_eval <<-CEVAL, __FILE__, __LINE__ + 1
          def #{query_method}(*args, &block)
            new_relation = clone
            new_relation.send(:apply_modules, Module.new(&block)) if block_given?
            value = Array.wrap(args.flatten).reject {|x| x.blank? }
            new_relation.#{query_method}_values += value if value.present?
            new_relation
          end
        CEVAL
      end

      class_eval <<-CEVAL, __FILE__, __LINE__ + 1
        def select(*args, &block)
          if block_given?
            to_a.select(&block)
          else
            new_relation = clone
            value = Array.wrap(args.flatten).reject {|x| x.blank? }
            new_relation.select_values += value if value.present?
            new_relation
          end
        end
      CEVAL

      [:where, :having].each do |query_method|
        class_eval <<-CEVAL, __FILE__, __LINE__ + 1
          def #{query_method}(*args, &block)
            new_relation = clone
            new_relation.send(:apply_modules, Module.new(&block)) if block_given?
            value = build_where(*args)
            new_relation.#{query_method}_values += Array.wrap(value) if value.present?
            new_relation
          end
        CEVAL
      end

      ActiveRecord::Relation::SINGLE_VALUE_METHODS.each do |query_method|
        attr_accessor :"#{query_method}_value"

        class_eval <<-CEVAL, __FILE__, __LINE__ + 1
          def #{query_method}(value = true, &block)
            new_relation = clone
            new_relation.send(:apply_modules, Module.new(&block)) if block_given?
            new_relation.#{query_method}_value = value
            new_relation
          end
        CEVAL
      end
    end

    def extending(*modules)
      new_relation = clone
      new_relation.send :apply_modules, *modules
      new_relation
    end

    def lock(locks = true, &block)
      relation = clone
      relation.send(:apply_modules, Module.new(&block)) if block_given?

      case locks
      when String, TrueClass, NilClass
        clone.tap {|new_relation| new_relation.lock_value = locks || true }
      else
        clone.tap {|new_relation| new_relation.lock_value = false }
      end
    end

    def reverse_order
      order_clause = arel.send(:order_clauses).join(', ')
      relation = except(:order)

      if order_clause.present?
        relation.order(reverse_sql_order(order_clause))
      else
        relation.order("#{@klass.table_name}.#{@klass.primary_key} DESC")
      end
    end

    def arel
      @arel ||= build_arel
    end

    def custom_join_sql(*joins)
      arel = table
      joins.each do |join|
        next if join.blank?

        @implicit_readonly = true

        case join
        when Hash, Array, Symbol
          if array_of_strings?(join)
            join_string = join.join(' ')
            arel = arel.join(join_string)
          end
        else
          arel = arel.join(join)
        end
      end
      arel.joins(arel)
    end

    def build_arel
      arel = table

      arel = build_joins(arel, @joins_values) if @joins_values.present?

      @where_values.uniq.each do |where|
        next if where.blank?

        case where
        when Arel::SqlLiteral
          arel = arel.where(where)
        else
          sql = where.is_a?(String) ? where : where.to_sql
          arel = arel.where(Arel::SqlLiteral.new("(#{sql})"))
        end
      end

      arel = arel.having(*@having_values.uniq.select{|h| h.present?}) if @having_values.present?

      arel = arel.take(@limit_value) if @limit_value.present?
      arel = arel.skip(@offset_value) if @offset_value.present?

      arel = arel.group(*@group_values.uniq.select{|g| g.present?}) if @group_values.present?

      arel = arel.order(*@order_values.uniq.select{|o| o.present?}.map(&:to_s)) if @order_values.present?

      selects = @select_values.uniq

      if selects.present?
        selects.each do |s|
          @implicit_readonly = false
          arel = arel.project(s) if s.present?
        end
      else
        arel = arel.project(@klass.quoted_table_name + '.*')
      end

      arel = arel.from(@from_value) if @from_value.present?

      case @lock_value
      when TrueClass
        arel = arel.lock
      when String
        arel = arel.lock(@lock_value)
      end if @lock_value.present?

      arel
    end

    def build_where(*args)
      return if args.blank?

      opts = args.first
      case opts
      when String, Array
        @klass.send(:sanitize_sql, args.size > 1 ? args : opts)
      when Hash
        attributes = @klass.send(:expand_hash_conditions_for_aggregates, opts)
        PredicateBuilder.new(table.engine).build_from_hash(attributes, table)
      else
        opts
      end
    end

    private

    def build_joins(relation, joins)
      joined_associations = []
{'fraction_non_alphanumeric': 0.10137554173732806, 'fraction_numerical': 0.0013190126248351234, 'mean_word_length': 2.2079177999395587, 'pattern_counts': {'":': 0, '<': 19, '<?xml version=': 0, '>': 5, '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': '5559925', 'n_tokens_mistral': 3335, 'n_tokens_neox': 3206, 'n_words': 688}