<commit_before>module ActiveRecord
  module ConnectionAdapters
    class PostgreSQLAdapter < AbstractAdapter
      def database_version
        select_value("SELECT version()")
      end

      def client_connections
        data = select(<<-SQL, "Client Connections")
                      SELECT client_addr   AS client_address
                           , datname       AS database
                           , pid           AS spid
                           , waiting       AS number_waiting
                           , query
                        FROM pg_stat_activity
                       ORDER BY 1, 2
                      SQL

        integer_columns = %w{
          spid
          number_waiting
        }

        data.each do |datum|
          integer_columns.each   { |c| datum[c] = datum[c].to_i }
        end

        data
      end

      def raw_activity_stats
        PgStatActivity.where(:datname => current_database).includes(:pg_locks)
      end

      def activity_stats
        data = raw_activity_stats
        data.collect do |record|
          conn = {'session_id' => record.pid}
          conn['xact_start']              = record.xact_start
          conn['last_request_start_time'] = record.query_start
          conn['command']                 = record.query
          conn['task_state']              = record.waiting
          conn['login']                   = record.usename
          conn['application']             = record.application_name
          conn['request_id']              = record.usesysid
          conn['net_address']             = record.client_addr
          conn['host_name']               = record.client_hostname
          conn['client_port']             = record.client_port
          conn['wait_time_ms']            = record.wait_time_ms

          if record.pg_locks.empty?
            conn['blocked_by'] = nil
          else
            conn['blocked_by'] = activity_stats_blocking_pid(data, record)
          end

          conn
        end
      end

      def activity_stats_blocking_pid(data, record)
        lock_info = record.pg_locks.detect { |lock| lock.granted == false }

        unless lock_info.nil?
          data.each do |data_record|
            next if data_record == record  || data_record.pg_locks.empty?

            stat_session_id = data_record.pid

            data_record.pg_locks.each do |current_lock|
              next unless current_lock.granted

              case current_lock.locktype
              when "relation"
                return stat_session_id if ['database', 'relation'].all? {|key| lock_info.send(key) == lock_info.send(key)}
              when "advisory"
                return stat_session_id if ['classid', 'objid', 'objsubid'].all? {|key| lock_info.send(key) == current_lock.send(key)}
              when "virtualxid"
                return stat_session_id if lock_info.virtualxid == current_lock.virtualxid
              when "transactionid"
                return stat_session_id if lock_info.transactionid == current_lock.transactionid
              when "tuple"
                return stat_session_id if ['database', 'relation', 'page', 'tuple'].all? {|key| lock_info.send(key) == current_lock.send(key)}
              end
            end
          end
        end

        return nil
      end

      # Taken from: https://github.com/bucardo/check_postgres/blob/2.19.0/check_postgres.pl#L3492
      # and referenced here: http://wiki.postgresql.org/wiki/Show_database_bloat
      # check_postgres is Copyright (C) 2007-2012, <NAME>
      #
      # Changes applied:
      # Removed  schemaname and totalwastedbytes columns from the original to fit our requirements.
      # Reformatted the SQL and renamed some columns to make them more easier to id.
      # Removed some CASE... logic statements as not needed for our requirements.
      def table_bloat
        data = select(<<-SQL, "Table Bloat")
                    SELECT tablename                                                    AS table_name
                         , reltuples::bigint                                            AS rows
                         , relpages::bigint                                             AS pages
                         , otta
                         , ROUND(CASE WHEN otta = 0 OR sml.relpages = 0 OR sml.relpages = otta THEN 0.0
                                 ELSE sml.relpages / otta::numeric END, 1)              AS percent_bloat
                         , CASE WHEN relpages < otta THEN 0
                                 ELSE relpages::bigint - otta                    END    AS wasted_pages
                         , CASE WHEN relpages < otta THEN 0
                                 ELSE (blocksize * (relpages - otta))::bigint    END    AS wasted_size
                         , CASE WHEN relpages < otta THEN 0<commit_msg>return the lock pid instead of the stat pid<commit_after>module ActiveRecord
  module ConnectionAdapters
    class PostgreSQLAdapter < AbstractAdapter
      def database_version
        select_value("SELECT version()")
      end

      def client_connections
        data = select(<<-SQL, "Client Connections")
                      SELECT client_addr   AS client_address
                           , datname       AS database
                           , pid           AS spid
                           , waiting       AS number_waiting
                           , query
                        FROM pg_stat_activity
                       ORDER BY 1, 2
                      SQL

        integer_columns = %w{
          spid
          number_waiting
        }

        data.each do |datum|
          integer_columns.each   { |c| datum[c] = datum[c].to_i }
        end

        data
      end

      def raw_activity_stats
        PgStatActivity.where(:datname => current_database).includes(:pg_locks)
      end

      def activity_stats
        data = raw_activity_stats
        data.collect do |record|
          conn = {'session_id' => record.pid}
          conn['xact_start']              = record.xact_start
          conn['last_request_start_time'] = record.query_start
          conn['command']                 = record.query
          conn['task_state']              = record.waiting
          conn['login']                   = record.usename
          conn['application']             = record.application_name
          conn['request_id']              = record.usesysid
          conn['net_address']             = record.client_addr
          conn['host_name']               = record.client_hostname
          conn['client_port']             = record.client_port
          conn['wait_time_ms']            = record.wait_time_ms

          if record.pg_locks.empty?
            conn['blocked_by'] = nil
          else
            conn['blocked_by'] = activity_stats_blocking_pid(data, record)
          end

          conn
        end
      end

      def activity_stats_blocking_pid(data, record)
        lock_info = record.pg_locks.detect { |lock| lock.granted == false }

        unless lock_info.nil?
          data.each do |data_record|
            next if data_record == record  || data_record.pg_locks.empty?

            data_record.pg_locks.each do |current_lock|
              next unless current_lock.granted

              case current_lock.locktype
              when "relation"
                return current_lock.pid if ['database', 'relation'].all? {|key| lock_info.send(key) == lock_info.send(key)}
              when "advisory"
                return current_lock.pid if ['classid', 'objid', 'objsubid'].all? {|key| lock_info.send(key) == current_lock.send(key)}
              when "virtualxid"
                return current_lock.pid if lock_info.virtualxid == current_lock.virtualxid
              when "transactionid"
                return current_lock.pid if lock_info.transactionid == current_lock.transactionid
              when "tuple"
                return current_lock.pid if ['database', 'relation', 'page', 'tuple'].all? {|key| lock_info.send(key) == current_lock.send(key)}
              end
            end
          end
        end

        return nil
      end

      # Taken from: https://github.com/bucardo/check_postgres/blob/2.19.0/check_postgres.pl#L3492
      # and referenced here: http://wiki.postgresql.org/wiki/Show_database_bloat
      # check_postgres is Copyright (C) 2007-2012, <NAME>
      #
      # Changes applied:
      # Removed  schemaname and totalwastedbytes columns from the original to fit our requirements.
      # Reformatted the SQL and renamed some columns to make them more easier to id.
      # Removed some CASE... logic statements as not needed for our requirements.
      def table_bloat
        data = select(<<-SQL, "Table Bloat")
                    SELECT tablename                                                    AS table_name
                         , reltuples::bigint                                            AS rows
                         , relpages::bigint                                             AS pages
                         , otta
                         , ROUND(CASE WHEN otta = 0 OR sml.relpages = 0 OR sml.relpages = otta THEN 0.0
                                 ELSE sml.relpages / otta::numeric END, 1)              AS percent_bloat
                         , CASE WHEN relpages < otta THEN 0
                                 ELSE relpages::bigint - otta                    END    AS wasted_pages
                         , CASE WHEN relpages < otta THEN 0
                                 ELSE (blocksize * (relpages - otta))::bigint    END    AS wasted_size
                         , CASE WHEN relpages < otta THEN 0
{'fraction_non_alphanumeric': 0.07448347107438016, 'fraction_numerical': 0.005371900826446281, 'mean_word_length': 1.4016373108409823, 'pattern_counts': {'":': 0, '<': 21, '<?xml version=': 0, '>': 9, 'https://': 2, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 20, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '930341', 'n_tokens_mistral': 2549, 'n_tokens_neox': 2389, 'n_words': 611}