aboutsummaryrefslogtreecommitdiffstats
path: root/activerecord/lib/active_record/connection_adapters/abstract_mysql_adapter.rb
Commit message (Collapse)AuthorAgeFilesLines
...
* Merge pull request #31422 from Edouard-chin/multistatement-fixturesMatthew Draper2018-01-241-0/+48
|\ | | | | Build a multi-statement query when inserting fixtures
| * Allow a 2 bytes margin:Edouard CHIN2018-01-231-1/+2
| | | | | | | | | | - mysql will add a 2 bytes margin to the statement, so given a `max_allowed_packet` set to 1024 bytes, a 1024 bytes fixtures will no be inserted (mysql will throw an error) - Preventing this by decreasing the max_allowed_packet by 2 bytes when doing the comparison with the actual statement size
| * Combine delete and insert statements in the same queryEdouard CHIN2018-01-221-7/+5
| |
| * Build a multi-statement query when inserting fixtures:Edouard CHIN2018-01-221-0/+49
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | - The `insert_fixtures` method can be optimized by making a single multi statement query for all fixtures having the same connection instead of doing a single query per table - The previous code was bulk inserting fixtures for a single table, making X query for X fixture files - This patch builds a single **multi statement query** for every tables. Given a set of 3 fixtures (authors, dogs, computers): ```ruby # before %w(authors dogs computers).each do |table| sql = build_sql(table) connection.query(sql) end # after sql = build_sql(authors, dogs, computers) connection.query(sql) ``` - `insert_fixtures` is now deprecated, `insert_fixtures_set` is the new way to go with performance improvement - My tests were done with an app having more than 700 fixtures, the time it takes to insert all of them was around 15s. Using a single multi statement query, it took on average of 8 seconds - In order for a multi statement to be executed, mysql needs to be connected with the `MULTI_STATEMENTS` [flag](https://dev.mysql.com/doc/refman/5.7/en/c-api-multiple-queries.html), which is done before inserting the fixtures by reconnecting to da the database with the flag declared. Reconnecting to the database creates some caveats: 1. We loose all open transactions; Inside the original code, when inserting fixtures, a transaction is open. Multple delete statements are [executed](https://github.com/rails/rails/blob/a681eaf22955734c142609961a6d71746cfa0583/activerecord/lib/active_record/fixtures.rb#L566) and finally the fixtures are inserted. The problem with this patch is that we need to open the transaction only after we reconnect to the DB otherwise reconnecting drops the open transaction which doesn't commit all delete statements and inserting fixtures doesn't work since we duplicated them (Primary key duplicate exception)... - In order to fix this problem, the transaction is now open directly inside the `insert_fixtures` method, right after we reconnect to the db - As an effect, since the transaction is open inside the `insert_fixtures` method, the DELETE statements need to be executed here since the transaction is open later 2. The same problem happens for the `disable_referential_integrity` since we reconnect, the `FOREIGN_KEY_CHECKS` is reset to the original value - Same solution as 1. , the disable_referential_integrity can be called after we reconnect to the transaction 3. When the multi statement query is executed, no other queries can be performed until we paginate over the set of results, otherwise mysql throws a "Commands out of sync" [Ref](https://dev.mysql.com/doc/refman/5.7/en/commands-out-of-sync.html) - Iterating over the set of results until `mysql_client.next_result` is false. [Ref](https://github.com/brianmario/mysql2#multiple-result-sets) - Removed the `active_record.sql "Fixture delete"` notification, the delete statements are now inside the INSERT's one - On mysql the `max_allowed_packet` is looked up: 1. Before executing the multi-statements query, we check the packet length of each statements, if the packet is bigger than the max_allowed_packet config, an `ActiveRecordError` is raised 2. Otherwise we concatenate the current sql statement into the previous and so on until the packet is `< max_allowed_packet`
* | `create_database` should not add default charset when `collation` is givenRyuta Kamizono2018-01-151-1/+1
| | | | | | | | | | | | | | | | | | | | | | | | | | If `collation` is given without `charset`, it may generate invalid SQL. For example `create_database(:matt_aimonetti, collation: "utf8mb4_bin")`: ``` > CREATE DATABASE `matt_aimonetti` DEFAULT CHARACTER SET `utf8` COLLATE `utf8mb4_bin`; ERROR 1253 (42000): COLLATION 'utf8mb4_bin' is not valid for CHARACTER SET 'utf8' ``` In MySQL, charset is used to find the default collation. If `collation` is given explicitly, it is not necessary to give extra charset.
* | Fix Illegal parameter data type bigint for operation 'get_lock' errorIvan Zinovyev2017-12-201-2/+2
| |
* | Remove passing needless empty string `options` in `create_table`Ryuta Kamizono2017-12-201-4/+0
| | | | | | | | Follow up of #31177.
* | Merge pull request #31177 from ↵Matthew Draper2017-12-201-1/+1
|\ \ | | | | | | | | | | | | albertoalmagro/remove-default-mysql-engine-from-ar-5-2 Remove default ENGINE=InnoDB for Mysql2 adapter
| * | Remove default ENGINE=InnoDB for Mysql2 adapterAlberto Almagro2017-12-111-1/+1
| |/ | | | | | | | | | | | | | | | | | | | | | | | | Before this commit ENGINE=InnoDB was added by default to Mysql2 adapter +create_table+ if no +options+ option was provided. This default ENGINE was lost as soon as something was passed in at +options+ option, making its goal and propagation inconsistent, as the programmer needed to remember including ENGINE=InnoDB when something was passed in. This commit removes default ENGINE as its use isn't needed anymore for current MySQL and MariaDB versions. It adds compatibility support and tests to ensure that default ENGINE is still present for migrations with version 5.1 and before. It also ensures we still dump the ENGINE option to +schema.rb+ in order to avoid inconsistencies.
* | Quote primary key in the subselect generated by mysql2 adapterRyuta Kamizono2017-12-191-1/+2
| | | | | | | | Otherwise it will occur syntax error if primary key is a reserved word.
* | Optimizing information_schema query for `foreign_keys`Hiroyuki Morita2017-12-131-2/+3
|/ | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Use CONSTRAINT_SCHEMA key for information_schema.referential_constraints. See https://dev.mysql.com/doc/refman/5.7/en/information-schema-optimization.html. ``` > EXPLAIN SELECT fk.referenced_table_name AS 'to_table', fk.referenced_column_name AS 'primary_key', fk.column_name AS 'column', fk.constraint_name AS 'name', rc.update_rule AS 'on_update', rc.delete_rule AS 'on_delete' FROM information_schema.referential_constraints rc JOIN information_schema.key_column_usage fk USING (constraint_schema, constraint_name) WHERE fk.referenced_column_name IS NOT NULL AND fk.table_schema = 'activerecord_unittest' AND fk.table_name = 'fk_test_has_pk' AND rc.constraint_schema = 'activerecord_unittest' AND rc.table_name = 'fk_test_has_pk'\G *************************** 1. row *************************** id: 1 select_type: SIMPLE table: rc partitions: NULL type: ALL possible_keys: NULL key: CONSTRAINT_SCHEMA,TABLE_NAME key_len: NULL ref: NULL rows: NULL filtered: NULL Extra: Using where; Open_full_table; Scanned 0 databases *************************** 2. row *************************** id: 1 select_type: SIMPLE table: fk partitions: NULL type: ALL possible_keys: NULL key: TABLE_SCHEMA,TABLE_NAME key_len: NULL ref: NULL rows: NULL filtered: NULL Extra: Using where; Open_full_table; Scanned 0 databases; Using join buffer (Block Nested Loop) 2 rows in set, 1 warning (0.00 sec) ```
* Extract duplicated index column options normalization as ↵Ryuta Kamizono2017-12-031-19/+0
| | | | | | | `options_for_index_columns` And placed `add_options_for_index_columns` in `schema_statements.rb` consistently to ease to find related code.
* Refactor `length`, `order`, and `opclass` index options dumpingRyuta Kamizono2017-12-031-1/+1
|
* Merge pull request #31230 from dinahshi/postgresql_extract_sqlMatthew Draper2017-12-031-25/+11
|\ | | | | Extract sql fragment generators from PostgreSQL adapter
| * Extract sql fragment generators for alter table from PostgreSQL adapterDinah Shi2017-12-021-25/+11
| |
* | Add new error class `QueryCanceled` which will be raised when canceling ↵Ryuta Kamizono2017-11-271-0/+3
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | statement due to user request (#31235) This changes `StatementTimeout` to `QueryCanceled` for PostgreSQL. In MySQL, errno 1317 (`ER_QUERY_INTERRUPTED`) is only used when the query is manually cancelled. But in PostgreSQL, `QUERY_CANCELED` error code (57014) which is used `StatementTimeout` is also used when the both case. And, we can not tell which reason happened. So I decided to introduce new error class `QueryCanceled` closer to the error code name.
* | Rename `TransactionTimeout` to more descriptive `LockWaitTimeout` (#31223)Ryuta Kamizono2017-11-271-1/+1
|/ | | | | | Since #31129, new error class `StatementTimeout` has been added. `TransactionTimeout` is caused by the timeout shorter than `StatementTimeout`, but its name is too generic. I think that it should be a name that understands the difference with `StatementTimeout`.
* Merge pull request #30510 from yhirano55/add_nodoc_to_activerecordEileen M. Uchitelle2017-11-251-1/+1
|\ | | | | Add :nodoc: to activerecord [ci skip]
| * Add :nodoc: to activerecord [ci skip]Yoshiyuki Hirano2017-09-031-1/+1
| |
* | Add new error class `StatementTimeout` which will be raised when statement ↵Ryuta Kamizono2017-11-131-0/+3
| | | | | | | | | | | | | | | | | | | | | | | | timeout exceeded (#31129) We are sometimes using The MAX_EXECUTION_TIME hint for MySQL depending on the situation. It will prevent catastrophic performance down by wrong performing queries. The new error class `StatementTimeout` will make to be easier to handle that case. https://dev.mysql.com/doc/refman/5.7/en/optimizer-hints.html#optimizer-hints-execution-time
* | [Active Record] require => require_relativeAkira Matsuda2017-10-211-10/+10
| | | | | | | | This basically reverts 9d4f79d3d394edb74fa2192e5d9ad7b09ce50c6d
* | Add JSON attribute test cases for SQLite3 adapterRyuta Kamizono2017-10-051-1/+0
| |
* | Prevent extra `column_for` for `change_column_{default,null,comment}`Ryuta Kamizono2017-09-231-7/+4
| | | | | | | | | | | | | | `change_column_{default,null,comment}` in mysql2 adapter are passing `column.sql_type` as `type` to `change_column` to intend keeping previous type. But `column_for` requires extra query, so use passing `nil` to `type` explicitly in the internal for the purpose.
* | `index_name` should be quotedRyuta Kamizono2017-09-221-1/+1
| |
* | Return nil if table comment is blankRyuta Kamizono2017-09-221-1/+1
| |
* | Implement change_table_comment and change_column_comment for MySql AdapterAlecs Popa2017-09-221-0/+10
|/
* Omit the default limit for float columns (#28041)Ryuta Kamizono2017-08-271-1/+1
|
* Merge pull request #30337 from kamipo/refactor_schema_dumperRyuta Kamizono2017-08-241-1/+0
|\ | | | | Refactor `SchemaDumper` to make it possible to adapter specific customization
| * Refactor `SchemaDumper` to make it possible to adapter specific customizationRyuta Kamizono2017-08-221-1/+0
| | | | | | | | | | | | | | Currently `SchemaDumper` is only customizable for column options. But 3rd party connection adapters (oracle-enhanced etc) need to customizable for table or index dumping also. To make it possible, I introduced adapter specific `SchemaDumper` classes for that.
* | Merge pull request #30360 from gcourtemanche/transaction_timedoutRafael França2017-08-221-0/+3
|\ \ | |/ |/| Add TransactionTimeout for MySQL error code 1205
| * Add TransactionTimeout for MySQL error code 1205Gabriel Courtemanche2017-08-221-0/+3
| |
* | Update links to use https instead of http [ci skip]Yoshiyuki Hirano2017-08-221-2/+2
|/
* Place `update_table_definition` consistently in `SchemaStatements`Ryuta Kamizono2017-08-211-4/+0
|
* Restore `to_sql` to return only SQL (#29945)Ryuta Kamizono2017-08-181-2/+1
| | | | Because `to_sql` is public API. I introduced `to_sql_and_binds` internal API to return SQL and binds.
* Use `predicate_builder.build_bind_attribute` wherever possibleRyuta Kamizono2017-07-281-1/+1
| | | | For less duplicated code.
* Fix build failures on MySQLSean Griffin2017-07-241-1/+1
| | | | | | There's an actual bug in 213796fb4936dce1da2f0c097a054e1af5c25c2c around prepared statements being disabled. I'm looking into it, but in the mean time this gets the build green so it doesn't block other PRs
* Refactor Active Record to let Arel manage bind paramsSean Griffin2017-07-241-1/+2
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | A common source of bugs and code bloat within Active Record has been the need for us to maintain the list of bind values separately from the AST they're associated with. This makes any sort of AST manipulation incredibly difficult, as any time we want to potentially insert or remove an AST node, we need to traverse the entire tree to find where the associated bind parameters are. With this change, the bind parameters now live on the AST directly. Active Record does not need to know or care about them until the final AST traversal for SQL construction. Rather than returning just the SQL, the Arel collector will now return both the SQL and the bind parameters. At this point the connection adapter will have all the values that it had before. A bit of this code is janky and something I'd like to refactor later. In particular, I don't like how we're handling associations in the predicate builder, the special casing of `StatementCache::Substitute` in `QueryAttribute`, or generally how we're handling bind value replacement in the statement cache when prepared statements are disabled. This also mostly reverts #26378, as it moved all the code into a location that I wanted to delete. /cc @metaskills @yahonda, this change will affect the adapters Fixes #29766. Fixes #29804. Fixes #26541. Close #28539. Close #24769. Close #26468. Close #26202. There are probably other issues/PRs that can be closed because of this commit, but that's all I could find on the first few pages.
* Merge pull request #29870 from kamipo/use_true_false_literalsSean Griffin2017-07-221-4/+4
|\ | | | | Use `TRUE` and `FALSE` boolean literals for MySQL
| * Use `TRUE` and `FALSE` boolean literals for MySQLRyuta Kamizono2017-07-201-4/+6
| | | | | | | | | | | | Since #29699, abstract boolean serialization has been changed to use `TRUE` and `FALSE` literals. MySQL also support the literals. So we can use the abstract boolean serialization even for MySQL.
* | Merge pull request #29869 from kamipo/make_type_map_to_privateRafael França2017-07-211-1/+1
|\ \ | | | | | | Make `type_map` to private because it is only used in the connection adapter
| * | Make `type_map` to private because it is only used in the connection adapterRyuta Kamizono2017-07-201-1/+1
| |/ | | | | | | | | | | | | `type_map` is an internal API and it is only used in the connection adapter. And also, some type map initializer methods requires passed `type_map`, but those instances already has `type_map` in itself. So we don't need explicit passing `type_map` to the initializers.
* / Use frozen-string-literal in ActiveRecordKir Shatrov2017-07-191-0/+2
|/
* Fix extracting MariaDB versionRyuta Kamizono2017-07-071-2/+6
| | | | | | Currently `version` method always returns `5.5.5` because the `full_version` is `5.5.5-10.x.y-MariaDB...` since MariaDB 10.x. It should be ignored if the prefix is `5.5.5-`.
* Remove database specific JSON typesRyuta Kamizono2017-07-051-3/+0
| | | | We already have database agnostic `Type::Json` since #29220.
* Merge branch 'master' into require_relative_2017Xavier Noria2017-07-021-14/+14
|\
| * Revert "Merge pull request #29540 from kirs/rubocop-frozen-string"Matthew Draper2017-07-021-1/+0
| | | | | | | | | | This reverts commit 3420a14590c0e6915d8b6c242887f74adb4120f9, reversing changes made to afb66a5a598ce4ac74ad84b125a5abf046dcf5aa.
| * Merge pull request #29540 from kirs/rubocop-frozen-stringMatthew Draper2017-07-021-0/+1
| |\ | | | | | | | | | Enforce frozen string in Rubocop
| | * Enforce frozen string in RubocopKir Shatrov2017-07-011-0/+1
| | |
| * | Merge pull request #29506 from pat/frozen-string-literalsMatthew Draper2017-07-021-4/+4
| |\ \ | | | | | | | | | | | | Make ActiveSupport frozen-string-literal friendly.
| | * | Make ActiveRecord frozen string literal friendly.Pat Allan2017-06-201-4/+4
| | | |