This file is indexed.

/usr/lib/ruby/vendor_ruby/sequel/extensions/to_dot.rb is in ruby-sequel 3.33.0-1.

This file is owned by root:root, with mode 0o644.

The actual contents of the file can be viewed below.

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
# This adds a <tt>Sequel::Dataset#to_dot</tt> method.  The +to_dot+ method
# returns a string that can be processed by graphviz's +dot+ program in
# order to get a visualization of the dataset.  Basically, it shows a version
# of the dataset's abstract syntax tree.

module Sequel
  class ToDot
    # The option keys that should be included in the dot output.
    TO_DOT_OPTIONS = [:with, :distinct, :select, :from, :join, :where, :group, :having, :compounds, :order, :limit, :offset, :lock].freeze

    # Given a +Dataset+, return a string in +dot+ format that will
    # generate a visualization of the dataset.
    def self.output(ds)
      new(ds).output
    end

    # Given a +Dataset+, parse the internal structure to generate
    # a dataset visualization.
    def initialize(ds)
      @i = 0
      @stack = [@i]
      @dot = ["digraph G {", "0 [label=\"self\"];"]
      v(ds, "")
      @dot << "}"
    end

    # Output the dataset visualization as a string in +dot+ format.
    def output
      @dot.join("\n")
    end

    private

    # Add an entry to the +dot+ output with the given label.  If +j+
    # is given, it is used directly as the node or transition.  Otherwise
    # a node is created for the current object.
    def dot(label, j=nil)
      @dot << "#{j||@i} [label=#{label.to_s.inspect}];"
    end

    # Recursive method that parses all of Sequel's internal datastructures,
    # adding the appropriate nodes and transitions to the internal +dot+
    # structure.
    def v(e, l)
      @i += 1
      dot(l, "#{@stack.last} -> #{@i}") if l
      @stack.push(@i)
      case e
      when LiteralString
        dot "#{e.inspect}.lit"
      when Symbol, Numeric, String, Class, TrueClass, FalseClass, NilClass
        dot e.inspect
      when Array
        dot "Array"
        e.each_with_index do |val, j|
          v(val, j)
        end
      when Hash
        dot "Hash"
        e.each do |k, val|
          v(val, k)
        end
      when SQL::ComplexExpression 
        dot "ComplexExpression: #{e.op}"
        e.args.each_with_index do |val, j|
          v(val, j)
        end
      when SQL::Identifier
        dot "Identifier"
        v(e.value, :value)
      when SQL::QualifiedIdentifier
        dot "QualifiedIdentifier"
        v(e.table, :table)
        v(e.column, :column)
      when SQL::OrderedExpression
        dot "OrderedExpression: #{e.descending ? :DESC : :ASC}#{" NULLS #{e.nulls.to_s.upcase}" if e.nulls}"
        v(e.expression, :expression)
      when SQL::AliasedExpression
        dot "AliasedExpression"
        v(e.expression, :expression)
        v(e.aliaz, :alias)
      when SQL::CaseExpression
        dot "CaseExpression"
        v(e.expression, :expression) if e.expression
        v(e.conditions, :conditions)
        v(e.default, :default)
      when SQL::Cast
        dot "Cast"
        v(e.expr, :expr)
        v(e.type, :type)
      when SQL::Function
        dot "Function: #{e.f}"
        e.args.each_with_index do |val, j|
          v(val, j)
        end
      when SQL::Subscript 
        dot "Subscript"
        v(e.f, :f)
        v(e.sub, :sub)
      when SQL::WindowFunction
        dot "WindowFunction"
        v(e.function, :function)
        v(e.window, :window)
      when SQL::Window
        dot "Window"
        v(e.opts, :opts)
      when SQL::PlaceholderLiteralString
        str = e.str
        str = "(#{str})" if e.parens
        dot "PlaceholderLiteralString: #{str.inspect}"
        v(e.args, :args)
      when SQL::JoinClause
        str = "#{e.join_type.to_s.upcase} JOIN"
        if e.is_a?(SQL::JoinOnClause)
          str << " ON"
        elsif e.is_a?(SQL::JoinUsingClause)
          str << " USING"
        end
        dot str
        v(e.table, :table)
        v(e.table_alias, :alias) if e.table_alias
        if e.is_a?(SQL::JoinOnClause)
          v(e.on, :on) 
        elsif e.is_a?(SQL::JoinUsingClause)
          v(e.using, :using) 
        end
      when Dataset
        dot "Dataset"
        TO_DOT_OPTIONS.each do |k|
          if val = e.opts[k]
            v(val, k.to_s) 
          end
        end
      else
        dot "Unhandled: #{e.inspect}"
      end
      @stack.pop
    end
  end

  class Dataset
    # Return a string that can be processed by the +dot+ program (included
    # with graphviz) in order to see a visualization of the dataset's
    # abstract syntax tree.
    def to_dot
      ToDot.output(self)
    end
  end
end