Class: Sqlglot::Query

Inherits:
Object
  • Object
show all
Defined in:
lib/sqlglot/query.rb

Overview

High-level query metadata extraction, inspired by Python’s sql-metadata.

Parses SQL once via the Rust FFI, then walks the resulting AST Hash in pure Ruby to extract tables, columns, aliases, subqueries, CTEs, etc. All properties are lazy-evaluated and cached.

Examples:

q = Sqlglot::Query.new(
  "SELECT u.name, COUNT(o.id) AS cnt FROM users AS u " \
  "JOIN orders AS o ON u.id = o.user_id WHERE u.active = true",
  dialect: :postgres
)
q.query_type        # => :select
q.tables            # => ["users", "orders"]
q.tables_aliases    # => {"u" => "users", "o" => "orders"}
q.columns           # => ["users.name", "orders.id", "users.id", ...]
q.output_columns    # => ["name", "cnt"]
q.columns_dict      # => {select: [...], join: [...], where: [...]}

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(sql, dialect: nil) ⇒ Query

Returns a new instance of Query.

Parameters:

  • sql (String)

    the SQL query

  • dialect (Symbol, String, nil) (defaults to: nil)

    the SQL dialect



25
26
27
28
29
# File 'lib/sqlglot/query.rb', line 25

def initialize(sql, dialect: nil)
  @sql = sql
  @dialect = dialect
  reset_cache!
end

Instance Attribute Details

#sqlString (readonly)

Returns the original SQL string.

Returns:

  • (String)

    the original SQL string



32
33
34
# File 'lib/sqlglot/query.rb', line 32

def sql
  @sql
end

Instance Method Details

#astHash

The parsed AST as a Ruby Hash.

Returns:

  • (Hash)


38
39
40
# File 'lib/sqlglot/query.rb', line 38

def ast
  @ast ||= Sqlglot.parse(@sql, dialect: @dialect)
end

#columnsArray<String>

All column references, alias-resolved and table-qualified where possible.

Returns:

  • (Array<String>)


76
77
78
# File 'lib/sqlglot/query.rb', line 76

def columns
  @columns ||= extract_all_columns
end

#columns_aliasesHash{String => Array<String>}

Map of column alias => array of source columns.

Returns:

  • (Hash{String => Array<String>})


101
102
103
# File 'lib/sqlglot/query.rb', line 101

def columns_aliases
  @columns_aliases ||= extract_columns_aliases
end

#columns_aliases_dictHash{Symbol => Array<String>}

Which query clause each column alias appears in.

Returns:

  • (Hash{Symbol => Array<String>})


115
116
117
# File 'lib/sqlglot/query.rb', line 115

def columns_aliases_dict
  @columns_aliases_dict ||= extract_columns_aliases_dict
end

#columns_aliases_namesArray<String>

Just the alias names.

Returns:

  • (Array<String>)


108
109
110
# File 'lib/sqlglot/query.rb', line 108

def columns_aliases_names
  columns_aliases.keys
end

#columns_dictHash{Symbol => Array<String>}

Columns grouped by the clause they appear in.

Returns:

  • (Hash{Symbol => Array<String>})

    Keys: :select, :where, :join, :group_by, :order_by, :having,

    :insert, :update
    


85
86
87
# File 'lib/sqlglot/query.rb', line 85

def columns_dict
  @columns_dict ||= extract_columns_dict
end

#commentsArray<String>

SQL comments found in the AST.

Returns:

  • (Array<String>)


180
181
182
# File 'lib/sqlglot/query.rb', line 180

def comments
  @comments ||= extract_comments
end

#generalizeString

Generalized SQL with literals replaced by placeholders. Useful for query fingerprinting.

Returns:

  • (String)


190
191
192
# File 'lib/sqlglot/query.rb', line 190

def generalize
  @generalize ||= build_generalized
end

#limit_and_offsetArray(Integer, Integer)?

Returns [limit, offset] or nil.

Returns:

  • (Array(Integer, Integer), nil)
    limit, offset

    or nil



154
155
156
# File 'lib/sqlglot/query.rb', line 154

def limit_and_offset
  @limit_and_offset ||= extract_limit_and_offset
end

#output_columnsArray<String>

The column names (or aliases) that the SELECT would produce.

Returns:

  • (Array<String>)


92
93
94
# File 'lib/sqlglot/query.rb', line 92

def output_columns
  @output_columns ||= extract_output_columns
end

#query_typeSymbol

The type of SQL statement.

Returns:

  • (Symbol)

    one of :select, :insert, :update, :delete, :create_table, :create_view, :drop_table, :drop_view, :alter_table, :truncate, :merge, :begin, :commit, :rollback, :explain, :use, :unknown



50
51
52
# File 'lib/sqlglot/query.rb', line 50

def query_type
  @query_type ||= detect_query_type
end

#subqueriesHash{String => String}

Subquery alias => regenerated SQL body (from FROM / JOIN only).

Returns:

  • (Hash{String => String})


140
141
142
# File 'lib/sqlglot/query.rb', line 140

def subqueries
  @subqueries ||= extract_subqueries
end

#subqueries_namesArray<String>

Just the subquery alias names.

Returns:

  • (Array<String>)


147
148
149
# File 'lib/sqlglot/query.rb', line 147

def subqueries_names
  subqueries.keys
end

#tablesArray<String>

All table names referenced in the query, with CTE names excluded.

Returns:

  • (Array<String>)


59
60
61
# File 'lib/sqlglot/query.rb', line 59

def tables
  @tables ||= extract_tables
end

#tables_aliasesHash{String => String}

Map of table alias => real table name.

Returns:

  • (Hash{String => String})


66
67
68
# File 'lib/sqlglot/query.rb', line 66

def tables_aliases
  @tables_aliases ||= extract_tables_aliases
end

#valuesArray

Values from an INSERT statement.

Returns:

  • (Array)


163
164
165
# File 'lib/sqlglot/query.rb', line 163

def values
  @values ||= extract_values
end

#values_dictHash{String => Object}

Column => value pairs for INSERT. Auto-generates column_N names if the INSERT has no explicit column list.

Returns:

  • (Hash{String => Object})


171
172
173
# File 'lib/sqlglot/query.rb', line 171

def values_dict
  @values_dict ||= extract_values_dict
end

#with_namesArray<String>

Names of CTE definitions.

Returns:

  • (Array<String>)


124
125
126
# File 'lib/sqlglot/query.rb', line 124

def with_names
  @with_names ||= extract_with_names
end

#with_queriesHash{String => String}

CTE name => regenerated SQL body.

Returns:

  • (Hash{String => String})


131
132
133
# File 'lib/sqlglot/query.rb', line 131

def with_queries
  @with_queries ||= extract_with_queries
end