aboutsummaryrefslogtreecommitdiffstats
path: root/activerecord/lib/active_record/connection_adapters/sqlite3/schema_statements.rb
diff options
context:
space:
mode:
Diffstat (limited to 'activerecord/lib/active_record/connection_adapters/sqlite3/schema_statements.rb')
-rw-r--r--activerecord/lib/active_record/connection_adapters/sqlite3/schema_statements.rb27
1 files changed, 18 insertions, 9 deletions
diff --git a/activerecord/lib/active_record/connection_adapters/sqlite3/schema_statements.rb b/activerecord/lib/active_record/connection_adapters/sqlite3/schema_statements.rb
index 58e5138e02..48277f0ae2 100644
--- a/activerecord/lib/active_record/connection_adapters/sqlite3/schema_statements.rb
+++ b/activerecord/lib/active_record/connection_adapters/sqlite3/schema_statements.rb
@@ -7,6 +7,10 @@ module ActiveRecord
# Returns an array of indexes for the given table.
def indexes(table_name)
exec_query("PRAGMA index_list(#{quote_table_name(table_name)})", "SCHEMA").map do |row|
+ # Indexes SQLite creates implicitly for internal use start with "sqlite_".
+ # See https://www.sqlite.org/fileformat2.html#intschema
+ next if row["name"].starts_with?("sqlite_")
+
index_sql = query_value(<<-SQL, "SCHEMA")
SELECT sql
FROM sqlite_master
@@ -17,19 +21,24 @@ module ActiveRecord
WHERE name = #{quote(row['name'])} AND type = 'index'
SQL
- /\sWHERE\s+(?<where>.+)$/i =~ index_sql
+ /\bON\b\s*"?(\w+?)"?\s*\((?<expressions>.+?)\)(?:\s*WHERE\b\s*(?<where>.+))?\z/i =~ index_sql
columns = exec_query("PRAGMA index_info(#{quote(row['name'])})", "SCHEMA").map do |col|
col["name"]
end
- # Add info on sort order for columns (only desc order is explicitly specified, asc is
- # the default)
orders = {}
- if index_sql # index_sql can be null in case of primary key indexes
- index_sql.scan(/"(\w+)" DESC/).flatten.each { |order_column|
- orders[order_column] = :desc
- }
+
+ if columns.any?(&:nil?) # index created with an expression
+ columns = expressions
+ else
+ # Add info on sort order for columns (only desc order is explicitly specified,
+ # asc is the default)
+ if index_sql # index_sql can be null in case of primary key indexes
+ index_sql.scan(/"(\w+)" DESC/).flatten.each { |order_column|
+ orders[order_column] = :desc
+ }
+ end
end
IndexDefinition.new(
@@ -40,7 +49,7 @@ module ActiveRecord
where: where,
orders: orders
)
- end
+ end.compact
end
def create_schema_dumper(options)
@@ -77,7 +86,7 @@ module ActiveRecord
scope = quoted_scope(name, type: type)
scope[:type] ||= "'table','view'"
- sql = "SELECT name FROM sqlite_master WHERE name <> 'sqlite_sequence'".dup
+ sql = +"SELECT name FROM sqlite_master WHERE name <> 'sqlite_sequence'"
sql << " AND name = #{scope[:name]}" if scope[:name]
sql << " AND type IN (#{scope[:type]})"
sql