aboutsummaryrefslogtreecommitdiffstats
path: root/activerecord/lib/active_record/connection_adapters
Commit message (Collapse)AuthorAgeFilesLines
* Avoid redundant `time.getutc` call if it is already utc time objectRyuta Kamizono2019-06-181-5/+5
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Currently `type.serialize` and `connection.{quote|type_cast}` for a time object always does `time.getutc` call regardless of whether it is already utc time object or not, that duplicated proccess (`connection.type_cast(type.serialize(time))`) allocates extra/useless time objects for each type casting. This avoids that redundant `time.getutc` call if it is already utc time object. In the case of a model has timestamps (`created_at` and `updated_at`), it avoids 6,000 time objects allocation for 1,000 times `model.save`. ```ruby ObjectSpace::AllocationTracer.setup(%i{path line type}) pp ObjectSpace::AllocationTracer.trace { 1_000.times { User.create } }.select { |k, _| k[0].end_with?("quoting.rb", "time_value.rb") } ``` Before (c104bfe424e6cebe9c8e85a38515327a6c88b1f8): ``` {["~/rails/activerecord/lib/active_record/connection_adapters/abstract/quoting.rb", 203, :T_ARRAY]=>[1004, 0, 778, 0, 1, 0], ["~/rails/activerecord/lib/active_record/connection_adapters/abstract/quoting.rb", 220, :T_STRING]=>[2, 0, 2, 1, 1, 0], ["~/rails/activerecord/lib/active_record/connection_adapters/abstract/quoting.rb", 209, :T_ARRAY]=>[8, 0, 8, 1, 1, 0], ["~/rails/activerecord/lib/active_record/connection_adapters/abstract/quoting.rb", 57, :T_ARRAY]=>[4, 0, 4, 1, 1, 0], ["~/rails/activemodel/lib/active_model/type/helpers/time_value.rb", 17, :T_DATA]=>[4000, 0, 3096, 0, 1, 0], ["~/rails/activerecord/lib/active_record/connection_adapters/abstract/quoting.rb", 120, :T_DATA]=>[2000, 0, 1548, 0, 1, 0], ["~/rails/activerecord/lib/active_record/connection_adapters/abstract/quoting.rb", 126, :T_STRING]=>[4000, 0, 3096, 0, 1, 0]} ``` After (this change): ``` {["~/rails/activerecord/lib/active_record/connection_adapters/abstract/quoting.rb", 203, :T_ARRAY]=>[1004, 0, 823, 0, 1, 0], ["~/rails/activerecord/lib/active_record/connection_adapters/abstract/quoting.rb", 220, :T_STRING]=>[2, 0, 2, 1, 1, 0], ["~/rails/activerecord/lib/active_record/connection_adapters/abstract/quoting.rb", 209, :T_ARRAY]=>[8, 0, 8, 1, 1, 0], ["~/rails/activerecord/lib/active_record/connection_adapters/abstract/quoting.rb", 57, :T_ARRAY]=>[4, 0, 4, 1, 1, 0], ["~/rails/activerecord/lib/active_record/connection_adapters/abstract/quoting.rb", 126, :T_STRING]=>[2000, 0, 1638, 0, 1, 0]} ```
* No allocation `Arel::Visitors::ToSql#visit`Ryuta Kamizono2019-06-151-2/+2
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Each `visit o, collector` allocates one extra array due to receiving args by splat array. https://github.com/rails/rails/blob/2c3332cc4c0fa77dbe2e13e8a792f80fbd8f4ad3/activerecord/lib/arel/visitors/visitor.rb#L27-L29 Currently 1,000 times `User.where(id: 1).to_sql` allocates 13,000 arrays in `visitor.accept`. This avoids receiving args by splat array, it makes `visitor.accept` no array allocation. ```ruby ObjectSpace::AllocationTracer.setup(%i{path line type}) pp ObjectSpace::AllocationTracer.trace { 1_000.times { User.where(id: 1).to_sql } }.select { |k, _| k[2] == :T_ARRAY && k[0].end_with?("visitor.rb", "to_sql.rb") } ``` Before (2c3332cc4c0fa77dbe2e13e8a792f80fbd8f4ad3): ``` {["~/rails/activerecord/lib/arel/visitors/to_sql.rb", 18, :T_ARRAY]=>[1000, 0, 0, 0, 0, 0], ["~/rails/activerecord/lib/active_record/connection_adapters/determine_if_preparable_visitor.rb", 11, :T_ARRAY]=>[1000, 0, 0, 0, 0, 0], ["~/rails/activerecord/lib/arel/visitors/visitor.rb", 12, :T_ARRAY]=>[1000, 0, 0, 0, 0, 0], ["~/rails/activerecord/lib/arel/visitors/to_sql.rb", 788, :T_ARRAY]=>[3000, 0, 0, 0, 0, 0], ["~/rails/activerecord/lib/arel/visitors/to_sql.rb", 794, :T_ARRAY]=>[3000, 0, 0, 0, 0, 0], ["~/rails/activerecord/lib/arel/visitors/to_sql.rb", 156, :T_ARRAY]=>[1000, 0, 0, 0, 0, 0], ["~/rails/activerecord/lib/arel/visitors/to_sql.rb", 443, :T_ARRAY]=>[1000, 0, 0, 0, 0, 0], ["~/rails/activerecord/lib/arel/visitors/to_sql.rb", 603, :T_ARRAY]=>[1000, 0, 0, 0, 0, 0], ["~/rails/activerecord/lib/arel/visitors/to_sql.rb", 611, :T_ARRAY]=>[1000, 0, 0, 0, 0, 0]} ``` After (this change): ``` {} ```
* Move while_preventing_writes from conn to handlereileencodes2019-06-142-15/+17
| | | | | | | | | | | | | | | | | If we put the `while_preventing_writes` on the connection then the middleware that sends reads to the primary and ensures they can't write will not work. The `while_preventing_writes` will only be applied to the connection which it's called on - which in the case of the middleware is Ar::Base. This worked fine if you called it directly like `OtherDbConn.connection.while_preventing_writes` but Rails didn't have a way of knowing you wanted to call it on all the connections. The change here moves the `while_preventing_writes` method from the connection to the handler so that it can block writes to all queries for that handler. This will apply to all the connections associated with that handler.
* Move SchemaMigration to migration_contexteileencodes2019-06-142-5/+20
| | | | | | | | | | | | | | | | | | | | | | | | | | This PR moves the `schema_migration` to `migration_context` so that we can access the `schema_migration` per connection. This does not change behavior of the SchemaMigration if you are using one database. This also does not change behavior of any public APIs. `Migrator` is private as is `MigrationContext` so we can change these as needed. We now need to pass a `schema_migration` to `Migrator` so that we can run migrations on the right connection outside the context of a rake task. The bugs this fixes were discovered while debugging the issues around the SchemaCache on initialization with multiple database. It was clear that `get_all_versions` wouldn't work without these changes outside the context of a rake task (because in the rake task we establish a connection and change AR::Base.connection to the db we're running on). Because the `SchemaCache` relies on the `SchemaMigration` information we need to make sure we store it per-connection rather than on ActiveRecord::Base. [Eileen M. Uchitelle & Aaron Patterson]
* Allocation on demand in transactionsRyuta Kamizono2019-06-141-20/+35
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Currently 1,000 transactions creates 10,000 objects regardless whether it is necessary or not. This makes allocation on demand in transactions, now 1,000 transactions creates required 5,000 objects only by default. ```ruby ObjectSpace::AllocationTracer.setup(%i{path line type}) pp ObjectSpace::AllocationTracer.trace { 1_000.times { User.create } }.select { |k, _| k[0].end_with?("transaction.rb") } ``` Before (95d038f): ``` {["~/rails/activerecord/lib/active_record/connection_adapters/abstract/transaction.rb", 209, :T_HASH]=>[1000, 0, 715, 0, 1, 0], ["~/rails/activerecord/lib/active_record/connection_adapters/abstract/transaction.rb", 210, :T_OBJECT]=>[1000, 0, 715, 0, 1, 0], ["~/rails/activerecord/lib/active_record/connection_adapters/abstract/transaction.rb", 210, :T_HASH]=>[1000, 0, 715, 0, 1, 0], ["~/rails/activerecord/lib/active_record/connection_adapters/abstract/transaction.rb", 80, :T_OBJECT]=>[1000, 0, 715, 0, 1, 0], ["~/rails/activerecord/lib/active_record/connection_adapters/abstract/transaction.rb", 8, :T_ARRAY]=>[1000, 0, 715, 0, 1, 0], ["~/rails/activerecord/lib/active_record/connection_adapters/abstract/transaction.rb", 81, :T_ARRAY]=>[1000, 0, 715, 0, 1, 0], ["~/rails/activerecord/lib/active_record/connection_adapters/abstract/transaction.rb", 289, :T_STRING]=>[1000, 0, 714, 0, 1, 0], ["~/rails/activerecord/lib/active_record/connection_adapters/abstract/transaction.rb", 116, :T_ARRAY]=>[1000, 0, 714, 0, 1, 0], ["~/rails/activerecord/lib/active_record/connection_adapters/abstract/transaction.rb", 120, :T_ARRAY]=>[1000, 0, 714, 0, 1, 0], ["~/rails/activerecord/lib/active_record/connection_adapters/abstract/transaction.rb", 121, :T_HASH]=>[1000, 0, 714, 0, 1, 0]} ``` After (this change): ``` {["~/rails/activerecord/lib/active_record/connection_adapters/abstract/transaction.rb", 213, :T_HASH]=>[1000, 0, 739, 0, 1, 0], ["~/rails/activerecord/lib/active_record/connection_adapters/abstract/transaction.rb", 214, :T_OBJECT]=>[1000, 0, 739, 0, 1, 0], ["~/rails/activerecord/lib/active_record/connection_adapters/abstract/transaction.rb", 214, :T_HASH]=>[1000, 0, 739, 0, 1, 0], ["~/rails/activerecord/lib/active_record/connection_adapters/abstract/transaction.rb", 81, :T_OBJECT]=>[1000, 0, 739, 0, 1, 0], ["~/rails/activerecord/lib/active_record/connection_adapters/abstract/transaction.rb", 304, :T_STRING]=>[1000, 0, 738, 0, 1, 0]} ```
* Make ActiveRecord `ConnectionPool.connections` thread-safe. (#36473)jeffdoering2019-06-131-1/+16
| | | | | | | | | | | | | | | | | | | | | | | * Make ActiveRecord `ConnectionPool.connections` thread-safe. ConnectionPool documentation is clear on the need to synchronize access to @connections but also states that public methods do not require synchronization. Existing code exposed @connections directly via attr_reader. The fix uses synchronize() to lock @connections then returns a copy to the caller using Array.dup(). Includes comments on the connections method that thread-safe access to the connections array does not imply thread-safety of accessing methods on the actual connections. Adds a test-case that modifies the pool using a supported method in one thread while a second thread accesses pool.connections. The test fails without this patch. Fixes #36465. * Update activerecord/test/cases/connection_pool_test.rb [jeffdoering + Rafael Mendonça França]
* Merge pull request #36472 from kamipo/empty_line_only_before_access_modifierRyuta Kamizono2019-06-1322-26/+0
|\ | | | | Enable `Layout/EmptyLinesAroundAccessModifier` cop
| * Enable `Layout/EmptyLinesAroundAccessModifier` copRyuta Kamizono2019-06-1322-26/+0
| | | | | | | | | | | | | | | | | | | | | | We sometimes say "✂️ newline after `private`" in a code review (e.g. https://github.com/rails/rails/pull/18546#discussion_r23188776, https://github.com/rails/rails/pull/34832#discussion_r244847195). Now `Layout/EmptyLinesAroundAccessModifier` cop have new enforced style `EnforcedStyle: only_before` (https://github.com/rubocop-hq/rubocop/pull/7059). That cop and enforced style will reduce the our code review cost.
* | Clear schema cache when a table is created/dropped/renamedRyuta Kamizono2019-06-134-0/+11
|/ | | | Otherwise `Model.table_exists?` returns the staled cache result.
* Allow column name with function (e.g. `length(title)`) as safe SQL stringRyuta Kamizono2019-06-104-8/+32
| | | | | | | | | | | | | | | | Currently, almost all "Dangerous query method" warnings are false alarm. As long as almost all the warnings are false alarm, developers think "Let's ignore the warnings by using `Arel.sql()`, it actually is false alarm in practice.", so I think we should effort to reduce false alarm in order to make the warnings valuable. This allows column name with function (e.g. `length(title)`) as safe SQL string, which is very common false alarm pattern, even in the our codebase. Related 6c82b6c99, 6607ecb2a, #36420. Fixes #32995.
* Allow `column_name AS alias` as safe SQL stringRyuta Kamizono2019-06-104-0/+4
|
* Refactor `disallow_raw_sql!` to avoid `split(/\s*,\s*/)` to order argsRyuta Kamizono2019-06-094-19/+54
| | | | | `split(/\s*,\s*/)` to order args and then `permit.match?` one by one is much slower than `permit.match?` once.
* Merge pull request #36420 from kamipo/quoted_identifier_regexRyuta Kamizono2019-06-064-5/+105
|\ | | | | Allow quoted identifier string as safe SQL string
| * Allow quoted identifier string as safe SQL stringRyuta Kamizono2019-06-064-5/+105
| | | | | | | | | | | | | | | | | | | | | | | | | | Currently `posts.title` is regarded as a safe SQL string, but `"posts"."title"` (it is a result of `quote_table_name("posts.title")`) is regarded as an unsafe SQL string even though a result of `quote_table_name` should obviously be regarded as a safe SQL string, since the column name matcher doesn't respect quotation, it is a little annoying. This changes the column name matcher to allow quoted identifiers as safe SQL string, now all results of the `quote_table_name` are regarded as safe SQL string.
* | Move schema cache from connection to pooleileencodes2019-06-054-5/+33
|/ | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | This PR proposes moving the schema cache from the connection to the pool so the connection can ask the pool for the cache. In a future PR our goal is to be able to read the yaml file from the pool so we can get rid of the `active_record.check_schema_cache_dump` initializer. This will fix the issues surrounding dumping the schema cache and mulitple databases. Why do we want to get rid of the initializer you ask? Well I was looking at #34449 and trying to make it work for our usecase and it revealed A LOT of problems. There are a few issues that I will fix in remaining PRs with SchemaMigration, but there's a big glaring issue with this initializer. When you have an application with multiple databases we'll need to loop through all the configurations and set the schema cache on those connections. The problem is on initialization we only have one connection - the one for Ar::Base. This is fine in a single db application but not fine in multi-db. If we follow the pattern in #34449 and establish a connection to those other dbs we will end up setting the cache on the _connection object_ rather than on all connections that connect for that config. So even though we looped through the configs and assigned the cache the cache will not be set (or will be set wrong) once the app is booted because the connection objects after boot are _different_ than the connection objects we assigned the cache to. After trying many different ways to set the schema cache `@tenderlove` and I came to the conclusion that the initializer is problematic, as is setting the schema cache twice. This is part 1 to move the cache to the pool so the cache can read from the schema cache yaml file instead of setting it when initializing the app. To do this we have created a `NullPool` that initializes an empty cache. I put the `get_schema_cache` and `set_schema_cache` in an `AbstractPool` so we can share code between `ConnectionPool` and `NullPool` instead of duplicating code. Now we only need to set the schema_cache on the pool rather than the connection. In `discard!` we need to unset the connection from the schema_cache - we still want the cache just not the connection.
* Fix sqlite3 collation parsing when using decimal columns.Martin Schuster2019-06-041-2/+2
| | | | | | If an sqlite3 table contains a decimal column behind columns with a collation definition, then parsing the collation of all preceeding columns will fail -- the collation will be missed without notice.
* Merge pull request #36384 from ↵Ryuta Kamizono2019-06-031-1/+1
|\ | | | | | | | | guigs/fix-invalid-schema-when-pk-column-has-comment Fix invalid schema dump when primary key column has a comment
| * Fix invalid schema dump when primary key column has a commentGuilherme Goettems Schneider2019-06-031-1/+1
| | | | | | | | | | | | | | | | Before this fix it would either generate an invalid schema, passing `comment` option twice to `create_table`, or it move the comment from primary key column to the table if table had no comment when the dump was generated. The situation now is that a comment on primary key will be ignored (not present on schema). Fixes #29966
* | Refactor `create_table`'s options separationRyuta Kamizono2019-06-032-12/+11
|/ | | | | | | | `create_table` and `t.column` have the same named options (e.g. `:comment`, `:primary_key`), so it should be separated table options from column options. Related #36373.
* Fix table comment also being applied to the primary key columnGuilherme Goettems Schneider2019-05-311-1/+1
|
* `:datetime` and `:time` columns allows `:precision` option [ci skip]Ryuta Kamizono2019-05-281-2/+3
|
* Use WeakRef to avoid leaking connection poolsJohn Hawthorn2019-05-271-11/+21
| | | | | | | | | | | | | | | | | | Prior to 3e2e8eeb9ea552bd4782538cf9348455f3d0e14a the Reaper thread would hold a reference to connection pools indefinitely, preventing the connection pool from being garbage collected, and also leaking the Thread. Since 3e2e8eeb9ea552bd4782538cf9348455f3d0e14a, there is only one Reaper Thread for all pools, however all pools are still stored in a class variable, preventing them from being garbage collected. This commit instead holds reference to the pools through a WeakRef. This way, connection pools referenced elsewhere will be reaped, any others will be able to be garbage collected. I don't love resorting to WeakRef to solve this, but I believe it's the simplest way to accomplish the the desired behaviour.
* Put all `explain` methods into `DatabaseStatements` moduleRyuta Kamizono2019-05-224-18/+14
| | | | | Almost all database statements methods except `explain` was moved into `DatabaseStatements` at #35922. This moves the last one method.
* Merge pull request #36296 from jhawthorn/dont_fear_the_reaperAaron Patterson2019-05-181-7/+25
|\ | | | | Use a single thread for all ConnectionPool Reapers
| * Use a single thread for all ConnectionPool ReapersJohn Hawthorn2019-05-171-7/+25
| | | | | | | | | | Previously we would spawn one thread per connection pool, which ends up being wasteful for apps with several connection pools.
* | Remove SQLite version support caveats [ci skip]Eugene Kenny2019-05-123-5/+3
|/ | | | | | | | | Since d1a74c1e012ed96f7179e53b9190b7da0a369e11, Active Record requires SQLite version 3.8.0 or greater, so savepoints and partial indexes are always available. That commit also added a runtime version check, so we can remove the minimum version requirement from the internal adapter documentation.
* Remove ignored_sql from SQLCounter by adding "TRANSACTION" to log nameYasuo Honda2019-05-084-12/+12
| | | | | | | | | | This commit adds "TRANSACTION" to savepoint and commit, rollback statements because none of savepoint statements were removed by #36153 since they are not "SCHEMA" statements. Although, only savepoint statements can be labeled as "TRANSACTION" I think all of transaction related method should add this label. Follow up #36153
* Should attempt `committed!`/`rolledback!` to all enrolled records in the ↵Ryuta Kamizono2019-05-071-4/+12
| | | | | | | | | | | | | | | | | | | | | | transaction Currently, `committed!`/`rolledback!` will only be attempted for the first enrolled record in the transaction, that will cause some problematic behaviors. The first one problem, `clear_transaction_record_state` won't be called even if the transaction is finalized except the first enrolled record. This means that de-duplicated records in the transaction won't refer latest state (e.g. won't happen rolling back record state). The second one problem, the enrolled order is not always the same as the order in which the actions actually happened, the first enrolled record may succeed no actions (e.g. `destroy` has already succeeded on another record during `before_destroy`), it will lose to fire any transactional callbacks. To avoid both problems, we should attempt `committed!`/`rolledback!` to all enrolled records in the transaction.
* Merge pull request #35998 from itsWill/add_documentation_for_add_indexEileen M. Uchitelle2019-04-191-0/+20
|\ | | | | Document algorithm: concurrent option for PostgreSQL [ci skip]
| * Document algorithm: concurrent options for PostgreSQL [ci skip]Guilherme Mansur2019-04-161-0/+20
| |
* | Merge pull request #35946 from alimi/cache-full-mysql-database-versionKasper Timm Hansen2019-04-163-5/+14
|\ \ | |/ |/| Cache full MySQL version in schema cache
| * Make changes per PR feedbackAli Ibrahim2019-04-122-9/+3
| | | | | | | | | | | | | | * Remove AbstractMysqlAdapter::Version since full_version_string will always be set. * Remove nodoc on private methods because private methods are not exposed in the docs.
| * Cache full MySQL version in schema cacheAli Ibrahim2019-04-113-6/+21
| | | | | | | | | | | | | | | | | | * The database version is cached in all the adapters, but this didn't include the full MySQL version. Anything that uses the full MySQL version would need to query the database to get that data even if they're using the schema cache. * Now the full MySQL version will be cached in the schema cache via the Version object.
* | make change_column_comment and change_table_comment invertibleYoshiyuki Kinjo2019-04-153-6/+21
| | | | | | | | | | | | | | | | | | We can revert migrations using `change_column_comment` or `change_table_comment` at current master. However, results are not what we expect: comments are remained in new status. This change tells previous comment to these methods in a way like `change_column_default`.
* | use PostgreSQL's bulk_alter_table implementationYoshiyuki Kinjo2019-04-133-41/+26
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Running this migration on mysql at current master fails because `add_references_for_alter` is missing. ``` change_table :users, bulk: true do |t| t.references :article end ``` This is also true for postgresql adapter, but its `bulk_alter_table` implementation can fallback in such case. postgresql's implementation is desirable to prevent unknown failure like this.
* | Refactor around sql_type metadata and columnRyuta Kamizono2019-04-124-33/+35
| | | | | | | | | | | | * remove useless `@type_metadata` and `@array` * move the compatibility code (for array) into column * etc.
* | Merge pull request #35922 from ↵Rafael França2019-04-112-80/+80
|\ \ | |/ |/| | | | | michaelglass/move-sqlite-3-database-statements-into-database-statements make SQLite3 `last_inserted_id` private and organize DatabaseStatement methods
| * moves sqlite3 methods that mirror Abstract::DatabaseStatements into ↵Michael Glass2019-04-102-80/+80
| | | | | | | | Sqlite3::DatabaseStatements and make those that are private in Abstract::DatabaseStatements private for sqlite3
* | Adding type option example to the documentation [ci skip] (#35917)Roberto Miranda2019-04-101-0/+1
|/ | | | | | | | | | | | * Adding type option example to the documentation [ci skip] It was hard for me looking https://api.rubyonrails.org/ to find that there was a type option. Adding this to the doc would be helpful especially for application with old tables where the references are still an integer not bigint * Update activerecord/lib/active_record/connection_adapters/abstract/schema_definitions.rb Co-Authored-By: robertomiranda <rjmaltamar@gmail.com>
* Accidentally lost `comment` in `Column#==` and `Column#hash`Ryuta Kamizono2019-04-101-2/+4
| | | | Refer #35875.
* Remove unused `sequence_name` in `sql_for_insert`Ryuta Kamizono2019-04-102-3/+3
| | | | | | | | | | All adapters (sqlite3, mysql2, postgresql, oracle-enhanced, sqlserver) doesn't use `sequence_name` in `sql_for_insert`. https://github.com/rsim/oracle-enhanced/blob/4e0db270a93859c9713fd079dbb315b9fe550e57/lib/active_record/connection_adapters/oracle_enhanced/database_statements.rb#L79-L85 https://github.com/rails-sqlserver/activerecord-sqlserver-adapter/blob/959fe8f49744460b876bc205c73259f8d4f37629/lib/active_record/connection_adapters/sqlserver/database_statements.rb#L226-L249 It can be handled in `exec_insert` like postgresql adapter if we want.
* There is no need to create `QueryAttribute` to just type cast a valueRyuta Kamizono2019-04-101-2/+1
|
* Merge pull request #35875 from Shopify/alloc-free-comparisonsRafael França2019-04-094-32/+38
|\ | | | | Improve == and hash methods on various schema cache structs to be allocation free.
| * Improve == and hash methods on various schema cache structs to be allocation ↵Jean Boussier2019-04-094-32/+38
| | | | | | | | | | | | | | | | free. The previous implementation would allocate 2 arrays per comparisons. I tried relying on Struct, but they do allocate one Hash inside `Struct#hash`.
* | Merge pull request #35909 from simi/alias-postgresql-adapterRyuta Kamizono2019-04-101-0/+1
|\ \ | | | | | | Bring back postgresql_version as an alias.
| * | Bring back postgresql_version as an alias.Josef Šimánek2019-04-091-0/+1
| |/
* / `get_database_version` is not public API [ci skip]Ryuta Kamizono2019-04-091-1/+1
|/
* Merge pull request #34800 from mqchau/mysqlCountDeleteRowInLockMatthew Draper2019-04-091-1/+3
|\ | | | | Wrap Mysql count of deleted rows in lock block to avoid conflict in test
| * Wrap Mysql count of deleted rows in lock block to avoid conflict in testQuan Chau2019-04-081-1/+3
| |
* | Merge pull request #35887 from kamipo/argument_errorRyuta Kamizono2019-04-093-6/+6
|\ \ | | | | | | Raise `ArgumentError` for invalid `:limit` and `:precision` like as other options