aboutsummaryrefslogtreecommitdiffstats
path: root/activerecord/lib
diff options
context:
space:
mode:
Diffstat (limited to 'activerecord/lib')
-rw-r--r--activerecord/lib/active_record/connection_adapters/abstract/database_statements.rb20
-rw-r--r--activerecord/lib/active_record/connection_adapters/abstract/query_cache.rb2
-rw-r--r--activerecord/lib/active_record/connection_adapters/abstract/schema_dumper.rb47
-rw-r--r--activerecord/lib/active_record/connection_adapters/abstract_mysql_adapter.rb7
-rw-r--r--activerecord/lib/active_record/connection_adapters/mysql/schema_dumper.rb25
-rw-r--r--activerecord/lib/active_record/connection_adapters/mysql/schema_statements.rb4
-rw-r--r--activerecord/lib/active_record/connection_adapters/postgresql/database_statements.rb3
-rw-r--r--activerecord/lib/active_record/connection_adapters/postgresql/schema_dumper.rb12
-rw-r--r--activerecord/lib/active_record/connection_adapters/postgresql/schema_statements.rb4
-rw-r--r--activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb37
-rw-r--r--activerecord/lib/active_record/connection_adapters/sqlite3/schema_statements.rb4
-rw-r--r--activerecord/lib/active_record/connection_adapters/sqlite3_adapter.rb7
-rw-r--r--activerecord/lib/active_record/relation.rb3
-rw-r--r--activerecord/lib/active_record/schema.rb2
-rw-r--r--activerecord/lib/active_record/schema_dumper.rb4
15 files changed, 78 insertions, 103 deletions
diff --git a/activerecord/lib/active_record/connection_adapters/abstract/database_statements.rb b/activerecord/lib/active_record/connection_adapters/abstract/database_statements.rb
index 5febb5a59f..4078345abf 100644
--- a/activerecord/lib/active_record/connection_adapters/abstract/database_statements.rb
+++ b/activerecord/lib/active_record/connection_adapters/abstract/database_statements.rb
@@ -10,6 +10,11 @@ module ActiveRecord
# Converts an arel AST to SQL
def to_sql(arel_or_sql_string, binds = [])
+ sql, _ = to_sql_and_binds(arel_or_sql_string, binds)
+ sql
+ end
+
+ def to_sql_and_binds(arel_or_sql_string, binds = []) # :nodoc:
if arel_or_sql_string.respond_to?(:ast)
unless binds.empty?
raise "Passing bind parameters with an arel AST is forbidden. " \
@@ -21,6 +26,7 @@ module ActiveRecord
[arel_or_sql_string.dup.freeze, binds]
end
end
+ private :to_sql_and_binds
# This is used in the StatementCache object. It returns an object that
# can be used to query the database repeatedly.
@@ -39,7 +45,7 @@ module ActiveRecord
# Returns an ActiveRecord::Result instance.
def select_all(arel, name = nil, binds = [], preparable: nil)
arel = arel_from_relation(arel)
- sql, binds = to_sql(arel, binds)
+ sql, binds = to_sql_and_binds(arel, binds)
if !prepared_statements || (arel.is_a?(String) && preparable.nil?)
preparable = false
else
@@ -138,22 +144,22 @@ module ActiveRecord
#
# If the next id was calculated in advance (as in Oracle), it should be
# passed in as +id_value+.
- def insert(arel, name = nil, pk = nil, id_value = nil, sequence_name = nil)
- sql, binds = to_sql(arel)
+ def insert(arel, name = nil, pk = nil, id_value = nil, sequence_name = nil, binds = [])
+ sql, binds = to_sql_and_binds(arel, binds)
value = exec_insert(sql, name, binds, pk, sequence_name)
id_value || last_inserted_id(value)
end
alias create insert
# Executes the update statement and returns the number of rows affected.
- def update(arel, name = nil)
- sql, binds = to_sql(arel)
+ def update(arel, name = nil, binds = [])
+ sql, binds = to_sql_and_binds(arel, binds)
exec_update(sql, name, binds)
end
# Executes the delete statement and returns the number of rows affected.
- def delete(arel, name = nil)
- sql, binds = to_sql(arel)
+ def delete(arel, name = nil, binds = [])
+ sql, binds = to_sql_and_binds(arel, binds)
exec_delete(sql, name, binds)
end
diff --git a/activerecord/lib/active_record/connection_adapters/abstract/query_cache.rb b/activerecord/lib/active_record/connection_adapters/abstract/query_cache.rb
index 41d93c4322..25622e34c8 100644
--- a/activerecord/lib/active_record/connection_adapters/abstract/query_cache.rb
+++ b/activerecord/lib/active_record/connection_adapters/abstract/query_cache.rb
@@ -95,7 +95,7 @@ module ActiveRecord
def select_all(arel, name = nil, binds = [], preparable: nil)
if @query_cache_enabled && !locked?(arel)
arel = arel_from_relation(arel)
- sql, binds = to_sql(arel, binds)
+ sql, binds = to_sql_and_binds(arel, binds)
cache_sql(sql, name, binds) { super(sql, name, binds, preparable: preparable) }
else
super
diff --git a/activerecord/lib/active_record/connection_adapters/abstract/schema_dumper.rb b/activerecord/lib/active_record/connection_adapters/abstract/schema_dumper.rb
index 9be26254b2..f17f1d35e2 100644
--- a/activerecord/lib/active_record/connection_adapters/abstract/schema_dumper.rb
+++ b/activerecord/lib/active_record/connection_adapters/abstract/schema_dumper.rb
@@ -1,5 +1,7 @@
# frozen_string_literal: true
+require "active_support/core_ext/hash/compact"
+
module ActiveRecord
module ConnectionAdapters # :nodoc:
# The goal of this module is to move Adapter specific column
@@ -20,38 +22,6 @@ module ActiveRecord
spec
end
- # This can be overridden on an Adapter level basis to support other
- # extended datatypes (Example: Adding an array option in the
- # PostgreSQL::ColumnDumper)
- def prepare_column_options(column)
- spec = {}
-
- if limit = schema_limit(column)
- spec[:limit] = limit
- end
-
- if precision = schema_precision(column)
- spec[:precision] = precision
- end
-
- if scale = schema_scale(column)
- spec[:scale] = scale
- end
-
- default = schema_default(column) if column.has_default?
- spec[:default] = default unless default.nil?
-
- spec[:null] = "false" unless column.null
-
- if collation = schema_collation(column)
- spec[:collation] = collation
- end
-
- spec[:comment] = column.comment.inspect if column.comment.present?
-
- spec
- end
-
# Lists the valid migration options
def migration_keys # :nodoc:
column_options_keys
@@ -59,6 +29,18 @@ module ActiveRecord
deprecate :migration_keys
private
+ def prepare_column_options(column)
+ spec = {}
+ spec[:limit] = schema_limit(column)
+ spec[:precision] = schema_precision(column)
+ spec[:scale] = schema_scale(column)
+ spec[:default] = schema_default(column)
+ spec[:null] = "false" unless column.null
+ spec[:collation] = schema_collation(column)
+ spec[:comment] = column.comment.inspect if column.comment.present?
+ spec.compact!
+ spec
+ end
def default_primary_key?(column)
schema_type(column) == :bigint
@@ -98,6 +80,7 @@ module ActiveRecord
end
def schema_default(column)
+ return unless column.has_default?
type = lookup_cast_type_from_column(column)
default = type.deserialize(column.default)
if default.nil?
diff --git a/activerecord/lib/active_record/connection_adapters/abstract_mysql_adapter.rb b/activerecord/lib/active_record/connection_adapters/abstract_mysql_adapter.rb
index 8a9c497918..1b4688a904 100644
--- a/activerecord/lib/active_record/connection_adapters/abstract_mysql_adapter.rb
+++ b/activerecord/lib/active_record/connection_adapters/abstract_mysql_adapter.rb
@@ -20,10 +20,6 @@ module ActiveRecord
include MySQL::ColumnDumper
include MySQL::SchemaStatements
- def update_table_definition(table_name, base) # :nodoc:
- MySQL::Table.new(table_name, base)
- end
-
##
# :singleton-method:
# By default, the Mysql2Adapter will consider all columns of type <tt>tinyint(1)</tt>
@@ -177,8 +173,7 @@ module ActiveRecord
#++
def explain(arel, binds = [])
- sql, binds = to_sql(arel, binds)
- sql = "EXPLAIN #{sql}"
+ sql = "EXPLAIN #{to_sql(arel, binds)}"
start = Time.now
result = exec_query(sql, "EXPLAIN", binds)
elapsed = Time.now - start
diff --git a/activerecord/lib/active_record/connection_adapters/mysql/schema_dumper.rb b/activerecord/lib/active_record/connection_adapters/mysql/schema_dumper.rb
index fbe3596dda..81f7dce562 100644
--- a/activerecord/lib/active_record/connection_adapters/mysql/schema_dumper.rb
+++ b/activerecord/lib/active_record/connection_adapters/mysql/schema_dumper.rb
@@ -4,24 +4,23 @@ module ActiveRecord
module ConnectionAdapters
module MySQL
module ColumnDumper # :nodoc:
- def prepare_column_options(column)
- spec = super
- spec[:unsigned] = "true" if column.unsigned?
-
- if supports_virtual_columns? && column.virtual?
- spec[:as] = extract_expression_for_virtual_column(column)
- spec[:stored] = "true" if /\b(?:STORED|PERSISTENT)\b/.match?(column.extra)
- spec = { type: schema_type(column).inspect }.merge!(spec)
- end
-
- spec
- end
-
def migration_keys
super + [:unsigned]
end
private
+ def prepare_column_options(column)
+ spec = super
+ spec[:unsigned] = "true" if column.unsigned?
+
+ if supports_virtual_columns? && column.virtual?
+ spec[:as] = extract_expression_for_virtual_column(column)
+ spec[:stored] = "true" if /\b(?:STORED|PERSISTENT)\b/.match?(column.extra)
+ spec = { type: schema_type(column).inspect }.merge!(spec)
+ end
+
+ spec
+ end
def default_primary_key?(column)
super && column.auto_increment? && !column.unsigned?
diff --git a/activerecord/lib/active_record/connection_adapters/mysql/schema_statements.rb b/activerecord/lib/active_record/connection_adapters/mysql/schema_statements.rb
index 1d87d60ba9..7bebe82065 100644
--- a/activerecord/lib/active_record/connection_adapters/mysql/schema_statements.rb
+++ b/activerecord/lib/active_record/connection_adapters/mysql/schema_statements.rb
@@ -62,6 +62,10 @@ module ActiveRecord
end
end
+ def update_table_definition(table_name, base)
+ MySQL::Table.new(table_name, base)
+ end
+
private
CHARSETS_OF_4BYTES_MAXLEN = ["utf8mb4", "utf16", "utf16le", "utf32"]
diff --git a/activerecord/lib/active_record/connection_adapters/postgresql/database_statements.rb b/activerecord/lib/active_record/connection_adapters/postgresql/database_statements.rb
index 0dd4aac463..8db2a645af 100644
--- a/activerecord/lib/active_record/connection_adapters/postgresql/database_statements.rb
+++ b/activerecord/lib/active_record/connection_adapters/postgresql/database_statements.rb
@@ -5,8 +5,7 @@ module ActiveRecord
module PostgreSQL
module DatabaseStatements
def explain(arel, binds = [])
- sql, binds = to_sql(arel, binds)
- sql = "EXPLAIN #{sql}"
+ sql = "EXPLAIN #{to_sql(arel, binds)}"
PostgreSQL::ExplainPrettyPrinter.new.pp(exec_query(sql, "EXPLAIN", binds))
end
diff --git a/activerecord/lib/active_record/connection_adapters/postgresql/schema_dumper.rb b/activerecord/lib/active_record/connection_adapters/postgresql/schema_dumper.rb
index 12c6603081..5031605c2a 100644
--- a/activerecord/lib/active_record/connection_adapters/postgresql/schema_dumper.rb
+++ b/activerecord/lib/active_record/connection_adapters/postgresql/schema_dumper.rb
@@ -4,19 +4,17 @@ module ActiveRecord
module ConnectionAdapters
module PostgreSQL
module ColumnDumper # :nodoc:
- # Adds +:array+ option to the default set
- def prepare_column_options(column)
- spec = super
- spec[:array] = "true" if column.array?
- spec
- end
-
# Adds +:array+ as a valid migration key
def migration_keys
super + [:array]
end
private
+ def prepare_column_options(column)
+ spec = super
+ spec[:array] = "true" if column.array?
+ spec
+ end
def default_primary_key?(column)
schema_type(column) == :bigserial
diff --git a/activerecord/lib/active_record/connection_adapters/postgresql/schema_statements.rb b/activerecord/lib/active_record/connection_adapters/postgresql/schema_statements.rb
index 780e642f21..f258203a43 100644
--- a/activerecord/lib/active_record/connection_adapters/postgresql/schema_statements.rb
+++ b/activerecord/lib/active_record/connection_adapters/postgresql/schema_statements.rb
@@ -586,6 +586,10 @@ module ActiveRecord
[super, *order_columns].join(", ")
end
+ def update_table_definition(table_name, base) # :nodoc:
+ PostgreSQL::Table.new(table_name, base)
+ end
+
private
def schema_creation
PostgreSQL::SchemaCreation.new(self)
diff --git a/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb b/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb
index 3b4439fc46..878c9c8ccd 100644
--- a/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb
+++ b/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb
@@ -76,7 +76,7 @@ module ActiveRecord
primary_key: "bigserial primary key",
string: { name: "character varying" },
text: { name: "text" },
- integer: { name: "integer" },
+ integer: { name: "integer", limit: 4 },
float: { name: "float" },
decimal: { name: "decimal" },
datetime: { name: "timestamp" },
@@ -368,10 +368,6 @@ module ActiveRecord
@use_insert_returning
end
- def update_table_definition(table_name, base) #:nodoc:
- PostgreSQL::Table.new(table_name, base)
- end
-
def column_name_for_operation(operation, node) # :nodoc:
OPERATION_ALIASES.fetch(operation) { operation.downcase }
end
@@ -439,9 +435,9 @@ module ActiveRecord
end
def initialize_type_map(m = type_map)
- register_class_with_limit m, "int2", Type::Integer
- register_class_with_limit m, "int4", Type::Integer
- register_class_with_limit m, "int8", Type::Integer
+ m.register_type "int2", Type::Integer.new(limit: 2)
+ m.register_type "int4", Type::Integer.new(limit: 4)
+ m.register_type "int8", Type::Integer.new(limit: 8)
m.register_type "oid", OID::Oid.new
m.register_type "float4", Type::Float.new
m.alias_type "float8", "float4"
@@ -508,17 +504,6 @@ module ActiveRecord
load_additional_types
end
- def extract_limit(sql_type)
- case sql_type
- when /^bigint/i, /^int8/i
- 8
- when /^smallint/i
- 2
- else
- super
- end
- end
-
# Extracts the value from a PostgreSQL column default definition.
def extract_value_from_default(default)
case default
@@ -703,18 +688,20 @@ module ActiveRecord
# Use standard-conforming strings so we don't have to do the E'...' dance.
set_standard_conforming_strings
+ variables = @config.fetch(:variables, {}).stringify_keys
+
# If using Active Record's time zone support configure the connection to return
# TIMESTAMP WITH ZONE types in UTC.
- # (SET TIME ZONE does not use an equals sign like other SET variables)
- if ActiveRecord::Base.default_timezone == :utc
- execute("SET time zone 'UTC'", "SCHEMA")
- elsif @local_tz
- execute("SET time zone '#{@local_tz}'", "SCHEMA")
+ unless variables["timezone"]
+ if ActiveRecord::Base.default_timezone == :utc
+ variables["timezone"] = "UTC"
+ elsif @local_tz
+ variables["timezone"] = @local_tz
+ end
end
# SET statements from :variables config hash
# https://www.postgresql.org/docs/current/static/sql-set.html
- variables = @config[:variables] || {}
variables.map do |k, v|
if v == ":default" || v == :default
# Sets the value to the global or compile default
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 c155e7f1ac..ee84646214 100644
--- a/activerecord/lib/active_record/connection_adapters/sqlite3/schema_statements.rb
+++ b/activerecord/lib/active_record/connection_adapters/sqlite3/schema_statements.rb
@@ -39,6 +39,10 @@ module ActiveRecord
end
end
+ def update_table_definition(table_name, base)
+ SQLite3::Table.new(table_name, base)
+ end
+
private
def schema_creation
SQLite3::SchemaCreation.new(self)
diff --git a/activerecord/lib/active_record/connection_adapters/sqlite3_adapter.rb b/activerecord/lib/active_record/connection_adapters/sqlite3_adapter.rb
index 8c12cb09bd..327ca34e77 100644
--- a/activerecord/lib/active_record/connection_adapters/sqlite3_adapter.rb
+++ b/activerecord/lib/active_record/connection_adapters/sqlite3_adapter.rb
@@ -99,10 +99,6 @@ module ActiveRecord
end
end
- def update_table_definition(table_name, base) # :nodoc:
- SQLite3::Table.new(table_name, base)
- end
-
def initialize(connection, logger, connection_options, config)
super(connection, logger, config)
@@ -203,8 +199,7 @@ module ActiveRecord
#++
def explain(arel, binds = [])
- sql, binds = to_sql(arel, binds)
- sql = "EXPLAIN QUERY PLAN #{sql}"
+ sql = "EXPLAIN QUERY PLAN #{to_sql(arel, binds)}"
SQLite3::ExplainPrettyPrinter.new.pp(exec_query(sql, "EXPLAIN", []))
end
diff --git a/activerecord/lib/active_record/relation.rb b/activerecord/lib/active_record/relation.rb
index caabad6055..d319978930 100644
--- a/activerecord/lib/active_record/relation.rb
+++ b/activerecord/lib/active_record/relation.rb
@@ -571,8 +571,7 @@ module ActiveRecord
conn = klass.connection
conn.unprepared_statement {
- sql, _ = conn.to_sql(relation.arel)
- sql
+ conn.to_sql(relation.arel)
}
end
end
diff --git a/activerecord/lib/active_record/schema.rb b/activerecord/lib/active_record/schema.rb
index f166c27fd9..1e121f2a09 100644
--- a/activerecord/lib/active_record/schema.rb
+++ b/activerecord/lib/active_record/schema.rb
@@ -39,7 +39,7 @@ module ActiveRecord
# The +info+ hash is optional, and if given is used to define metadata
# about the current schema (currently, only the schema's version):
#
- # ActiveRecord::Schema.define(version: 20380119000001) do
+ # ActiveRecord::Schema.define(version: 2038_01_19_000001) do
# ...
# end
def self.define(info = {}, &block)
diff --git a/activerecord/lib/active_record/schema_dumper.rb b/activerecord/lib/active_record/schema_dumper.rb
index 27a1c89bd1..fd644225ca 100644
--- a/activerecord/lib/active_record/schema_dumper.rb
+++ b/activerecord/lib/active_record/schema_dumper.rb
@@ -243,7 +243,9 @@ HEADER
end
def remove_prefix_and_suffix(table)
- table.gsub(/^(#{@options[:table_name_prefix]})(.+)(#{@options[:table_name_suffix]})$/, "\\2")
+ prefix = Regexp.escape(@options[:table_name_prefix].to_s)
+ suffix = Regexp.escape(@options[:table_name_suffix].to_s)
+ table.sub(/\A#{prefix}(.+)#{suffix}\z/, "\\1")
end
def ignored?(table_name)