aboutsummaryrefslogtreecommitdiffstats
path: root/activerecord/lib/active_record/connection_adapters
Commit message (Collapse)AuthorAgeFilesLines
* minor grammar fix [ci skip]Shivam Jain2019-02-241-1/+1
|
* Address "warning: in `column': the last argument was passed as a single Hash"Ryuta Kamizono2019-02-212-4/+4
|
* Extract `default_uniqueness_comparison` to ease to handle mismatched ↵Ryuta Kamizono2019-02-211-0/+4
| | | | | | | | | | | | | | | | | | collation issues In MySQL, the default collation is case insensitive. Since the uniqueness validator enforces case sensitive comparison by default, it frequently causes mismatched collation issues (performance, weird behavior, etc) to MySQL users. https://grosser.it/2009/12/11/validates_uniqness_of-mysql-slow/ https://github.com/rails/rails/issues/1399 https://github.com/rails/rails/pull/13465 https://github.com/gitlabhq/gitlabhq/commit/c1dddf8c7d947691729f6d64a8ea768b5c915855 https://github.com/huginn/huginn/pull/1330#discussion_r55152573 This extracts `default_uniqueness_comparison` to ease to handle the mismatched collation issues on the connection.
* Merge pull request #35263 from hatch-carl/reduce-postgres-uuid-allocationsRyuta Kamizono2019-02-211-3/+6
|\ | | | | Reduce unused allocations when casting UUIDs for Postgres
| * Reduce unused allocations when casting UUIDs for PostgresCarl Thuringer2019-02-201-3/+6
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Using the subscript method `#[]` on a string has several overloads and rather complex implementation. One of the overloads is the capability to accept a regular expression and then run a match, then return the receiver (if it matched) or one of the groups from the MatchData. The function of the `UUID#cast` method is to cast a UUID to a type and format acceptable by postgres. Naturally UUIDs are supposed to be string and of a certain format, but it had been determined that it was not ideal for the framework to send just any old string to Postgres and allow the engine to complain when "foobar" or "" was sent, being obviously of the wrong format for a valid UUID. Therefore this code was written to facilitate the checking, and if it were not of the correct format, a `nil` would be returned as is conventional in Rails. Now, the subscript method will allocate one or more strings on a match and return one of them, based on the index parameter. However, there is no need for a new string, as a UUID of the correct format is already such, and so long as the format was verified then the string supplied is adequate for consumption by the database. The subscript method also creates a MatchData object which will never be used, and so must eventually be garbage collected. Garbage collection indeed. This innocuous method tends to be called quite a lot, for example if the primary key of a table is a uuid, then this method will be called. If the foreign key of a relation is a UUID, once again this method is called. If that foreign key is belonging to a has_many relationship with dozens of objects, then again dozens of UUIDs shall be cast to a dup of themselves, and spawn dozens of MatchData objects, and so on. So, for users that: * Use UUIDs as primary keys * Use Postgres * Operate on collections of objects This accomplishes a significant savings in total allocations, and may save many garbage collections.
* | PostgreSQL: Support endless range values for range typesRyuta Kamizono2019-02-202-2/+2
|/
* Fix the regex that extract mismatched foreign key informationRyuta Kamizono2019-02-171-8/+18
| | | | | | | | | | | | | The CI failure for `test_errors_for_bigint_fks_on_integer_pk_table` is due to the poor regex that extract all ``` `(\w+)` ``` like parts from the message (`:foreign_key` should be `"old_car_id"`, but `"engines"`): https://travis-ci.org/rails/rails/jobs/494123455#L1703 I've improved the regex more strictly and have more exercised mismatched foreign key tests. Fixes #35294
* Merge pull request #35297 from yhara/fix-ar-connection-handler-leakRyuta Kamizono2019-02-161-7/+11
|\ | | | | | | Fix possible memory leak of ConnectionHandler
| * Fix possible memory leak of ConnectionHandlerYutaka HARA2019-02-161-7/+11
| | | | | | | | refs #35296
* | Refactor `remove_foreign_key` to delete the foreign key before `alter_table`Ryuta Kamizono2019-02-161-4/+2
|/
* Properly handle cached queries with too many bind parametersMatthew Dunbar2019-02-141-0/+6
|
* Add `remove_foreign_key` for `change_table`Ryuta Kamizono2019-02-111-0/+11
|
* SQLite3: Implement `add_foreign_key` and `remove_foreign_key`Ryuta Kamizono2019-02-115-6/+34
| | | | | | | | | | | | I implemented Foreign key create in `create_table` for SQLite3 at #24743. This follows #24743 to implement `add_foreign_key` and `remove_foreign_key`. Unfortunately SQLite3 has one limitation that `PRAGMA foreign_key_list(table-name)` doesn't have constraint name. So we couldn't implement find/remove foreign key by name for now. Fixes #35207. Closes #31343.
* More exercise table name prefix and suffix testsRyuta Kamizono2019-02-114-8/+16
|
* Merge pull request #35203 from chiastolite/add_column_without_column_namesRyuta Kamizono2019-02-101-0/+1
|\ | | | | | | Do not allow to add column without column name
| * Do not allow to add column without column nameHiroyuki Morita2019-02-101-0/+1
|/
* Refactor to extract defining column methods as `define_column_methods`Ryuta Kamizono2019-02-093-142/+161
| | | | | It makes to ease to handle all short-hand methods (e.g. validates arguments etc).
* Fix elapsed time calculationsbogdanvlviv2019-02-082-6/+6
| | | | | | | | | | | | | | | | | | | I've found a few places in Rails code base where I think it makes sense to calculate elapsed time more precisely by using `Concurrent.monotonic_time`: - Fix calculation of elapsed time in `ActiveSupport::Cache::MemoryStore#prune` - Fix calculation of elapsed time in `ActiveRecord::ConnectionAdapters::ConnectionPool::Queue#wait_poll` - Fix calculation of elapsed time in `ActiveRecord::ConnectionAdapters::ConnectionPool#attempt_to_checkout_all_existing_connections` - Fix calculation of elapsed time in `ActiveRecord::ConnectionAdapters::Mysql2Adapter#explain` See https://docs.ruby-lang.org/en/2.5.0/Process.html#method-c-clock_gettime https://blog.dnsimple.com/2018/03/elapsed-time-with-ruby-the-right-way Related to 7c4542146f0dde962205e5a90839349631ae60fb
* Relax sqlite3 version dependencySergey Ponomarev2019-02-041-1/+1
|
* Merge pull request #35089 from ↵Eileen M. Uchitelle2019-02-041-1/+1
|\ | | | | | | | | eileencodes/fix-query-cache-for-database-switching Invalidate all query caches for current thread
| * Invalidate query cache for all connections in the current threadEileen Uchitelle2019-02-011-1/+1
| | | | | | | | | | | | This change ensures that all query cahces are cleared across all connections per handler for the current thread so if you write on one connection the read will have the query cache cleared.
* | Merge pull request #35105 from olivierlacan/document-table-foreign-keyGannon McGibbon2019-02-021-1/+2
|\ \ | | | | | | Hint at advanced options for foreign_key
| * | Hint at advanced options for foreign_keyOlivier Lacan2019-01-301-1/+2
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | We sometimes display simple examples of additional parameters that can be supplied to table-wise methods like these and I found it particularly difficult to figure out which options `t.foreign_key` accepts without drilling very deep into the specific SchemaStatements docs. Since it's relatively common to create foreign keys with custom column names or primary keys, it seems like this should help quite a few people. [ci skip]
* | | Merge pull request #35082 from Shopify/eagerly-materialize-test-transactionsRafael França2019-02-011-2/+5
|\ \ \ | |_|/ |/| | Eagerly materialize the fixtures transaction
| * | Eagerly materialize the fixtures transactionJean Boussier2019-01-291-2/+5
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | The transaction used to restore fixtures is an implementation detail that should be abstracted away. Idealy a test should behave the same wether or not transactional fixtures are enabled. However since transactions have been made lazy, the fixture transaction started leaking into tests case. e.g. consider the following (oversimplified) test: ```ruby class SQLSubscriber attr_accessor :sql def initialize @sql = [] end def call(*, event) sql << event[:sql] end end subscriber = SQLSubscriber.new ActiveSupport::Notifications.subscribe("sql.active_record", subscriber) User.connection.execute('SELECT 1', 'Generic name') assert_equal ['SELECT 1'], subscriber.sql ``` On Rails 6 it starts to break because the `sql` array will be `['BEGIN', 'SELECT 1']`. Several things are wrong here: - That transaction is not generated by the tested code, so it shouldn't be visible. - The transaction is not even closed yet, which again doesn't reflect the reality.
* | | Remove unused attr_writers `visitor` and `indexes`Ryuta Kamizono2019-02-012-7/+0
|/ / | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | I deprecated two unused attr_writers `visitor` and `indexes` at 8056fe0 and f4bc364 conservatively, since those are accidentaly exposed in the docs. https://api.rubyonrails.org/v5.2/classes/ActiveRecord/ConnectionAdapters/AbstractAdapter.html https://api.rubyonrails.org/v5.2/classes/ActiveRecord/ConnectionAdapters/TableDefinition.html But I've found that `view_renderer` attr_writer is removed without deprecation at #35093, that is also exposed in the doc. https://api.rubyonrails.org/v5.2/classes/ActionView/Base.html I'd like to also remove the deprecated attr_writers since I think that removing `visitor` and `indexes` attr_writers is as safe as removing `view_renderer` attr_writer.
* | Allow changing text and blob size without giving the `limit` optionRyuta Kamizono2019-01-293-4/+21
| | | | | | | | | | | | | | | | | | | | | | | | | | | | In MySQL, the text column size is 65,535 bytes by default (1 GiB in PostgreSQL). It is sometimes too short when people want to use a text column, so they sometimes change the text size to mediumtext (16 MiB) or longtext (4 GiB) by giving the `limit` option. Unlike MySQL, PostgreSQL doesn't allow the `limit` option for a text column (raises ERROR: type modifier is not allowed for type "text"). So `limit: 4294967295` (longtext) couldn't be used in Action Text. I've allowed changing text and blob size without giving the `limit` option, it prevents that migration failure on PostgreSQL.
* | PostgreSQL: Use native timestamp decoders of pg-1.1Lars Kanis2019-01-261-0/+30
| | | | | | | | | | This improves performance of timestamp conversion and avoids additional string allocations.
* | Make `t.timestamps` with precision by defaultRyuta Kamizono2019-01-266-4/+22
| |
* | Fix `t.timestamps` missing `null: false` in `change_table bulk: true`Ryuta Kamizono2019-01-262-0/+4
| |
* | Allow `column_exists?` giving options without typeRyuta Kamizono2019-01-261-1/+1
| |
* | Fix error raised when handler doesn't existEileen Uchitelle2019-01-251-1/+10
|/ | | | | | | | | | | | | | | | | | | | | | | | | | | | | | While working on another feature for multiple databases (auto-switching) I observed that in development the first request won't autoload the application record connection for the primary database and may not yet know about the replica connection. In my test application this caused the application to thrown an error if I tried to send the first request to the replica before the replica was connected. This wouldn't be an issue in production because the application is preloaded. In order to fix this I decided to leave the original error message and delete the new error message. I updated the original error message to include the `role` to make it a bit clearer that the connection isn't established for that particular role. The error now reads: ``` No connection pool with 'primary' found for the 'reading' role. ``` A single database application will continue uisng the original error message: ``` No connection pool with 'primary' found. ```
* Allow `column_exists?` to be passed `type` argument as a stringRyuta Kamizono2019-01-241-1/+1
| | | | | | | | | | | Currently `conn.column_exists?("testings", "created_at", "datetime")` returns false even if the table has the `created_at` column. That reason is that `column.type` is a symbol but passed `type` is not normalized to symbol unlike `column_name`, it is surprising behavior to me. I've improved that to normalize a value before comparison.
* MySQL 8.0.14 adds `ER_FK_INCOMPATIBLE_COLUMNS`Yasuo Honda2019-01-221-1/+2
| | | | | | | | | | | | https://dev.mysql.com/doc/relnotes/mysql/8.0/en/news-8-0-14.html > Error messages relating to creating and dropping foreign keys > were improved to be more specific and informative. (Bug #28526309, Bug #92087) https://dev.mysql.com/doc/refman/8.0/en/server-error-reference.html > Error number: 3780; Symbol: ER_FK_INCOMPATIBLE_COLUMNS; SQLSTATE: HY000 > Message: Referencing column '%s' and referenced column '%s' in foreign key constraint '%s' are incompatible. > ER_FK_INCOMPATIBLE_COLUMNS was added in 8.0.14.
* Fix type casting column default in `change_column`Ryuta Kamizono2019-01-202-24/+42
| | | | | | | | | | | | | | Since #31230, `change_column` is executed as a bulk statement. That caused incorrect type casting column default by looking up the before changed type, not the after changed type. In a bulk statement, we can't use `change_column_default_for_alter` if the statement changes the column type. This fixes the type casting to use the constructed target sql_type. Fixes #34938.
* Merge pull request #34969 from eileencodes/fix-error-message-for-multi-db-appsEileen M. Uchitelle2019-01-181-1/+20
|\ | | | | Fix error message when adapter is not specified
| * Fix error message when adapter is not specifiedEileen Uchitelle2019-01-171-1/+20
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | When we added support for multiple databases through a 3-tiered config and configuration objects this error message got a bit convoluted. Previously if you had an application with a missing configuation and multiple databases the error message would look like this: ``` 'doesnexist' database is not configured. Available: development, development, test, test, production, production (ActiveRecord::AdapterNotSpecified) ``` That's not very descriptive since it duplicates the environments (because there are multiple databases per environment for this application). To fix this I've constructed a bit more readable error message which now reads like this if you have a multi db app: ``` The `doesntexist` database is not configured for the `production` environment. (ActiveRecord::AdapterNotSpecified) Available databases configurations are: development: primary, primary_readonly test: primary, primary_readonly production: primary, primary_readonly ``` And like this if you have a single db app: ``` The `doesntexist` database is not configured for the `production` environment. (ActiveRecord::AdapterNotSpecified) Available databases configurations are: development test ``` This makes the error message more readable and presents the user all available options for the database connections.
* | Remove deprecated `#set_state` from the transaction objectRafael Mendonça França2019-01-171-18/+0
| |
* | Remove deprecated `#supports_statement_cache?` from the database adaptersRafael Mendonça França2019-01-171-7/+0
| |
* | Remove deprecated `#insert_fixtures` from the database adaptersRafael Mendonça França2019-01-172-21/+1
| |
* | Remove deprecated ↵Rafael Mendonça França2019-01-171-5/+0
| | | | | | | | `ActiveRecord::ConnectionAdapters::SQLite3Adapter#valid_alter_table_type?`
* | Change `SQLite3Adapter` to always represent boolean values as integersRafael Mendonça França2019-01-172-20/+13
|/
* Remove public `prevent_writes` writerRyuta Kamizono2019-01-151-5/+5
| | | | | | The `@prevent_writes` should be updated only in the `while_preventing_writes`, it is not necessary to expose the attr writer.
* Deprecate `connection.visitor = ...` which is not released internal usageRyuta Kamizono2019-01-151-2/+6
| | | | | | | | | This attr writer was introduced at 7db90aa, but the usage is already removed at bd2f5c0 before v3.2.0.rc1 is released. If we'd like to customize the visitor in the connection, `arel_visitor` which is implemented in all adapters (mysql2, postgresql, sqlite3, oracle-enhanced, sqlserver) could be used for the purpose #23515.
* Remove `id_value` argument which is no longer passed to `sql_for_insert`Ryuta Kamizono2019-01-112-3/+3
| | | | Since #26002, `id_value` is no longer passed to `sql_for_insert`.
* Refactor `build_relation` in the uniqueness validator to avoid low level ↵Ryuta Kamizono2019-01-112-7/+16
| | | | predicate construction
* Enable `Lint/UselessAssignment` cop to avoid unused variable warnings (#34904)Ryuta Kamizono2019-01-091-2/+2
| | | | | | | | | | | | | | * Enable `Lint/UselessAssignment` cop to avoid unused variable warnings Since we've addressed the warning "assigned but unused variable" frequently. 370537de05092aeea552146b42042833212a1acc 3040446cece8e7a6d9e29219e636e13f180a1e03 5ed618e192e9788094bd92c51255dda1c4fd0eae 76ebafe594fc23abc3764acc7a3758ca473799e5 And also, I've found the unused args in c1b14ad which raises no warnings by the cop, it shows the value of the cop.
* :recycle: Fix mysql type map for enum and setbannzai2019-01-081-2/+2
|
* Merge the redundant `when Symbol` case to the `when String, ...`Ryuta Kamizono2019-01-041-2/+1
|
* 2x faster `connection.type_cast`Ryuta Kamizono2019-01-041-6/+1
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | `nil`, `Numeric`, and `String` are most basic objects which are passed to `type_cast`. But now each `when *types_which_need_no_typecasting` evaluation allocates extra two arrays, it makes `type_cast` slower. The `types_which_need_no_typecasting` was introduced at #15351, but the method isn't useful (never used any adapters) since all adapters (sqlite3, mysql2, postgresql, oracle-enhanced, sqlserver) still overrides the `_type_cast`. Just expanding the method would make the `type_cast` 2x faster. ```ruby module ActiveRecord module TypeCastFast def type_cast_fast(value, column = nil) value = id_value_for_database(value) if value.is_a?(Base) if column value = type_cast_from_column(column, value) end _type_cast_fast(value) rescue TypeError to_type = column ? " to #{column.type}" : "" raise TypeError, "can't cast #{value.class}#{to_type}" end private def _type_cast_fast(value) case value when Symbol, ActiveSupport::Multibyte::Chars, Type::Binary::Data value.to_s when true then unquoted_true when false then unquoted_false # BigDecimals need to be put in a non-normalized form and quoted. when BigDecimal then value.to_s("F") when nil, Numeric, String then value when Type::Time::Value then quoted_time(value) when Date, Time then quoted_date(value) else raise TypeError end end end end conn = ActiveRecord::Base.connection conn.extend ActiveRecord::TypeCastFast Benchmark.ips do |x| x.report("type_cast") { conn.type_cast("foo") } x.report("type_cast_fast") { conn.type_cast_fast("foo") } x.compare! end ``` ``` Warming up -------------------------------------- type_cast 58.733k i/100ms type_cast_fast 101.364k i/100ms Calculating ------------------------------------- type_cast 708.066k (± 5.9%) i/s - 3.583M in 5.080866s type_cast_fast 1.424M (± 2.3%) i/s - 7.197M in 5.055860s Comparison: type_cast_fast: 1424240.0 i/s type_cast: 708066.0 i/s - 2.01x slower ```