Module: Sqlglot::AstWalker Private

Defined in:
lib/sqlglot/ast_walker.rb

Overview

This module is part of a private API. You should avoid using this module if possible, as it may be removed or be changed in the future.

Generic helpers for traversing the JSON AST Hash returned by parse.

The AST is a nested structure of Hashes and Arrays. Statement and expression types appear as single-key Hashes:

{"Column" => {"name" => "id", "table" => "users", ...}}
{"Number" => "42"}
{"BinaryOp" => {"left" => ..., "op" => "Eq", "right" => ...}}

Class Method Summary collapse

Class Method Details

.extract_columns(node) ⇒ Array<Hash>

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Collect all Column references within an expression subtree. Returns an array of {name:, table:} hashes.

Parameters:

  • node (Hash, Array)

Returns:

  • (Array<Hash>)


58
59
60
61
62
# File 'lib/sqlglot/ast_walker.rb', line 58

def extract_columns(node)
  find_all(node, "Column").map do |col|
    { name: col["name"], table: col["table"] }
  end
end

.extract_value(node) ⇒ Integer, ...

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Convert an AST literal node to a Ruby value.

{"Number" => "42"}         => 42
{"Number" => "3.14"}       => 3.14
{"StringLiteral" => "foo"} => "foo"
{"Boolean" => true}        => true
{"Null" => ...}            => nil

Parameters:

  • node (Hash)

Returns:

  • (Integer, Float, String, true, false, nil)


74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
# File 'lib/sqlglot/ast_walker.rb', line 74

def extract_value(node)
  return nil unless node.is_a?(Hash)

  if node.key?("Number")
    num = node["Number"]
    num.include?(".") ? num.to_f : num.to_i
  elsif node.key?("StringLiteral")
    node["StringLiteral"]
  elsif node.key?("Boolean")
    node["Boolean"]
  elsif node.key?("Null")
    nil
  else
    # Unknown literal type -- return the raw node.
    node
  end
end

.find_all(node, type_key) ⇒ Array<Object>

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Collect all nodes of a given AST type anywhere in the subtree.

Parameters:

  • node (Hash, Array)

    the AST subtree

  • type_key (String)

    e.g. “Column”, “Table”, “Function”

Returns:

  • (Array<Object>)

    the value side of each matching node



45
46
47
48
49
50
51
# File 'lib/sqlglot/ast_walker.rb', line 45

def find_all(node, type_key)
  results = []
  walk(node) do |key, value, _|
    results << value if key == type_key
  end
  results
end

.node_type(node) ⇒ String?

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Return the single AST type key of a node, if it has exactly one capitalised key (the standard pattern).

Parameters:

  • node (Hash)

Returns:

  • (String, nil)


97
98
99
100
101
102
103
104
# File 'lib/sqlglot/ast_walker.rb', line 97

def node_type(node)
  return nil unless node.is_a?(Hash)

  node.each_key do |k|
    return k if k.is_a?(String) && k =~ /\A[A-Z]/
  end
  nil
end

.unwrap(node) ⇒ Hash

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Unwrap nested single-key wrappers to get the inner payload.

For example:

{"Expr" => {"expr" => {"Column" => {...}}, "alias" => nil}}

Parameters:

  • node (Hash)

Returns:

  • (Hash)


113
114
115
116
117
118
119
# File 'lib/sqlglot/ast_walker.rb', line 113

def unwrap(node)
  return node unless node.is_a?(Hash) && node.size == 1

  key = node.keys.first
  val = node.values.first
  val.is_a?(Hash) ? val : node
end

.walk(node) {|type_key, value, node| ... } ⇒ Object

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Depth-first walk of the AST. Yields every Hash node whose single key is a recognised AST type name (capitalised, e.g. “Column”).

Parameters:

  • node (Hash, Array, Object)

    the AST subtree

Yield Parameters:

  • type_key (String)

    the AST type name

  • value (Object)

    the contents of that node

  • node (Hash)

    the full single-key Hash



25
26
27
28
29
30
31
32
33
34
35
36
37
38
# File 'lib/sqlglot/ast_walker.rb', line 25

def walk(node, &block)
  case node
  when Hash
    node.each do |key, value|
      # Yield if this looks like a typed AST node (capitalised key).
      if key.is_a?(String) && key =~ /\A[A-Z]/
        yield(key, value, node)
      end
      walk(value, &block)
    end
  when Array
    node.each { |child| walk(child, &block) }
  end
end