Commit Graph

22654 Commits

Author SHA1 Message Date
Nikita Vasilevsky
91dad14385
Use _read_attribute in associations preloader instead of public reader
Using `ActiveModel::AttributeMethods#[]` or `AttributeMethods#read_attribute` is
not suitable when association involves a model with `id` column which is
not a whole primary key but still used as a foreign key. Public reader
treats `id` as an idenfitier and thus returns value for the primary key
column and not the `id` column. By using `_read_attribute` reader we can
ensure we are reading the column value directly.

Co-authored-by: Paarth Madan <paarth.madan@shopify.com>
2023-05-05 16:58:06 +00:00
Ben Toews
215d50cf2d
Clarify difference in docs between AR #and and #merge methods 2023-05-05 09:27:39 -06:00
fatkodima
cabc1842b7 Make increment_counter/decrement_counter accept an amount argument 2023-05-05 12:18:31 +03:00
Luan Vieira
ec7f5a1193
Avoid nested #with_raw_connection
At GitHub we're trying to switch over from the GitHub
activerecord-trilogy-adapter to the one in Rails. One difference between
the adapters is that the GitHub one did not have the `#select_all`
method that abandons multi results.

This wouldn't be a problem, except we also have more aggressive query
retries. This led to an issue because the `super` call in `#select_all`
leads to a nested `#with_raw_connection` call. If we experienced
transient connection errors during the query, the inner
`#with_raw_connection` could reconnect leaving the outer block with a
closed connection. In that case, calling `#more_results_exist?` results
in a `Trilogy::ConnectionClosed Attempted to use closed connection`.
That's the scenario described in this comment
7e735451a7/activerecord/lib/active_record/connection_adapters/abstract_adapter.rb (L981-L983)

Moving the call to `super` out of the `#with_raw_connection` block will
avoid the nesting and fix the issue. We prefer that solution over
detecting nested `#with_raw_connections` and preventing reconnects when
nested, since in our case we actually do want to reconnect and retry.

We're hoping this change is ok even though it's not strictly necessary
for general Rails users. We don't believe it has any downsides.
We did not add a test for this case since it's not possible to occur in
Rails itself. It's specific to custom GitHub code.

Co-authored-by: Daniel Colson <composerinteralia@github.com>
2023-05-04 11:43:59 -04:00
Jean Boussier
018b2ae377
Merge pull request #48120 from a5-stable/rewhere-with-nil
Allow passing nil to rewhere method
2023-05-04 13:49:51 +02:00
a5-stable
0924095748 allow rewhere to pass nil and return unscope(:where) 2023-05-04 20:31:19 +09:00
Eileen M. Uchitelle
dae86240a2
Merge pull request #47892 from ghiculescu/check-pending-crash
Fix error in `ActiveRecord::Migration.check_pending!`
2023-05-03 12:23:43 -05:00
Eileen M. Uchitelle
5947ec2d06
Merge pull request #48112 from adrianna-chang-shopify/ac-shared-mysql-db-statements
Clean up shared DB statements code between Mysql2 and Trilogy
2023-05-03 11:52:07 -05:00
Adrianna Chang
630ddc707e
Move shared database logic to MySQL::DatabaseStatements 2023-05-03 10:11:27 -04:00
Eileen M. Uchitelle
6cee8343f1
Merge pull request #48101 from joshuay03/fix-broken-includes-order-ids
[Fix #48080] Use `group` over `distinct` in `ActiveRecord::Calculations#ids` with `includes(...).order(...)`
2023-05-03 08:33:09 -05:00
Joshua Young
e856d7f1a2 [Fixes #48080] Fix broken distinct in ActiveRecord::Calculations#ids with includes(...).order(...) 2023-05-03 11:07:23 +10:00
Jean Boussier
10285e977b
Merge pull request #48111 from adrianna-chang-shopify/ac-trilogy-translate-error-use-match
Use `#include?` with String instead of Regexp for Trilogy conn errors
2023-05-02 20:46:26 +02:00
Adrianna Chang
11cc54dd25
Use String instead of Regexp when checking #include? for Trilogy conn errors 2023-05-02 14:25:09 -04:00
Adrianna Chang
abe0b123bc
Remove AbstractMysqlAdapterTest
This test was added in 8f5095a to ensure that there was coverage
for `AbstractMysqlAdapter#execute`, but 63c0d6b refactored `#execute`
to be defined at the Abstract adapter level, and rely on concrete MySQL
adapters to implement `#raw_execute`.

This test won't pass without having the `ExampleMysqlAdapter` implement
`#raw_execute`, but this test is obsolete now that AbstractMysql2Adapter
doesn't implement `#execute` directly.
2023-05-02 09:15:01 -04:00
Adrianna Chang
93b5fc1f95
Rename MySQL::DatabaseStatements => Mysql2::DatabaseStatements 2023-05-02 09:08:25 -04:00
Jean Boussier
2fd61a97c8 Add a test for querying serialized attributes containing Module
Extracted from https://github.com/rails/rails/pull/47352
2023-05-02 10:59:12 +02:00
Jean Boussier
b717a5a0d4 Revert "Merge pull request #47352 from basecamp/ar-freeze-cached"
This reverts commit 2c20f90ebae3fdd4d7e3351aeaffc4ad2c472069, reversing
changes made to 912096d4ce930b8e7e5d91e0c86bae2091fda0e4.
2023-05-02 10:53:14 +02:00
Jorge Manrubia
f195e033ac Freeze casted values instead of original values in database queries
This deals with a problem introduced in #7743ab95b8e15581f432206245c691434a3993d1a751b9d451170956d59457a9R8
that was preventing query `Class` serialized attributes. Duplicating the original
`Class` argument generates an anonymous class that can't be serialized as YAML.

This change makes query attributes hasheable based on their frozen casted values
to prevent the problem.

This solution is based on an idea by @matthewd from https://github.com/rails/rails/issues/47338#issuecomment-1424402777.
2023-05-02 10:09:20 +02:00
Shivam Chahar
e0ad2e7962 Fix flaky test in AR - token for
pass time arg to @user.touch
2023-04-28 16:40:00 +05:30
John Hawthorn
9eab88a557
Merge pull request #48084 from aharpole/trilogy-collation-compatibility
In older migrations, allow column collation to be explicitly specified
2023-04-27 12:50:26 -07:00
Aaron Harpole
ac63587cb7 In older migrations, allow column collation to be explicitly specified 2023-04-27 12:21:00 -07:00
Yong Bakos
6fe65ec3e6 CounterCache: Normalize example counter column names.
The documentation uses the default pluralized model name with
the _count suffix (eg posts_count). However, the documentation
examples for #update_counters deviates from this.

Use the default-style counter column names in the example code
for #update_counters, to be consistent.
2023-04-27 11:17:59 -07:00
fatkodima
45bff1623e Allow insert_all/upsert_all to use indexes with columns not in the same order as in :unique_by 2023-04-27 17:55:41 +03:00
Jean Boussier
976c48779e
Merge pull request #47767 from joshuay03/fix-updated-at-not-updating-in-before-update
Fix #45389 | `updated_at` not updating in `before_update` callback
2023-04-27 16:14:56 +02:00
John Kelly
c837ae624b Add intersects? to Relation
Ruby 3.1 added `intersects?` which is equivalent to `(a & b).any?`. Rubocop added a corresponding cop, `Style/ArrayIntersect`, which transforms the old style to use `intersect?`. Unfortunately as `intersects?` is not delegated on `CollectionProxy`, this leads to false positives that need to be disabled for no good reason other than the fact the method isn't delegated.

This PR add delegation of `intersects?` to `Relation` which fixes this.
2023-04-27 16:09:34 +02:00
alpaca-tc
ec0a2a9d98 The deferrable foreign key can be passed to t.references.
Fixed a bug in which deferrable foreign_key was ignored when passed to `t.references`.
2023-04-27 10:43:58 +09:00
alpaca-tc
896d35910a Deprecate deferrable: true option of add_foreign_key.
`deferrable: true` is deprecated in favor of `deferrable: :immediate`, and
will be removed in Rails 7.2.

Because `deferrable: true` and `deferrable: :deferred` are hard to understand.
Both true and :deferred are truthy values.
This behavior is the same as the deferrable option of the add_unique_key method, added in #46192.

*Hiroyuki Ishii*
2023-04-26 21:48:17 +09:00
Jean Boussier
3a32921a0a Make Adapter#exec_query clear the query cache
It's public API and we can't assume whether the query is read only
so we should clear the cache.

To perform read only queries, `select` and `select_all` can be used.
2023-04-26 12:59:51 +02:00
Jean Boussier
dfa6af68f6 Rename uses_transactions to materialize_transactions
It's hard to understand what `use_transactions` does.
2023-04-26 12:35:50 +02:00
Jean Boussier
5a51610c33
Merge pull request #48039 from ghiculescu/ar-encryption-default-proc
Fix `Marshal.dump` on records that use AR Encryption
2023-04-26 09:04:36 +02:00
Rafael Mendonça França
3a1662f714
Merge pull request #46864 from palkan/feat/arel-function-tables
Support function table names in Arel Table
2023-04-25 14:31:16 -04:00
Rafael Mendonça França
fb4881270b
Merge PR #46843 2023-04-25 18:27:08 +00:00
Rafael Mendonça França
15a7b1ada5
Copy edits on the commit to avoid exposing this class in public API 2023-04-25 18:26:27 +00:00
Jean Boussier
2fa766d9bc
Merge pull request #48061 from Shopify/ar-execute-clear-cache
Active Record: clear query cache automatically when calling `#execute`
2023-04-25 16:46:10 +02:00
Jean Boussier
fe6876415d Get rid of AbstractMysqlAdapter#query
It is now unused.
2023-04-25 16:18:31 +02:00
Jean Boussier
e7baa9798b
Merge pull request #48062 from Shopify/trilogy-disconnect-tests
TrilogyAdapter: implement AdapterConnectionTest primitives
2023-04-25 16:02:49 +02:00
Jean Boussier
63c0d6b31b Active Record: clear query cache automatically when calling #execute
Also refactor #execute to be defined in AbstractAdapter.
2023-04-25 15:55:10 +02:00
Jean Boussier
af97f7e564 TrilogyAdapter: implement AdapterConnectionTest primitives
The tests were skipped.
2023-04-25 15:26:55 +02:00
fatkodima
7130e3cfc4 Fix find_or_create_by/find_or_create_by! when used within concurrent transactions 2023-04-25 12:09:26 +03:00
Jean Boussier
eb3a17414a TrilogyAdapter: add some missing nodoc and remove a dead method 2023-04-25 09:24:34 +02:00
Jean Boussier
8e39e0def6 Extract Trilogy::DatabaseStatements
To be consistent with other adapters.
2023-04-25 09:24:34 +02:00
Jean Boussier
f902999b47 Make TrilogyAdapter #each_hash and #error_number private
They were never meant to be public.
2023-04-25 09:24:34 +02:00
Jean Boussier
f69bbcbc07 MySQL2 and TrilogyAdapter: stop using #execute as internal API
`#execute` is a public method and using it internaly forces us to expose
private arguments and other dirty things.

Other adapters don't do this, so this bring MySQL in line with others.
2023-04-25 09:24:34 +02:00
Yasuo Honda
e93bd8fde0
Merge pull request #48048 from tiramizoo/pg-1-5-warning
Fix pg 1.5.0 deprecation warning
2023-04-25 16:13:30 +09:00
Xavier Noria
08d66afcb5 Use RDoc markup 2023-04-25 08:42:20 +02:00
Wojciech Wnętrzak
f05de69c17
Fix pg 1.5 deprecation warning
Closes #48046
2023-04-25 08:39:23 +02:00
Xavier Noria
73e57e4dc5 Document query cache invalidation for raw_connection 2023-04-25 08:28:29 +02:00
Yasuo Honda
744b6715a5
Merge pull request #48040 from fatkodima/fix-deprecation-referential_integrity_test
Fix a deprecation in `referential_integrity_test.rb` file
2023-04-24 21:10:49 +09:00
Jean Boussier
77fa5584a3
Merge pull request #48015 from rails/fix-trilogy-builds-retry
Fix trilogy builds
2023-04-24 09:54:35 +02:00
Jean Boussier
5aabcba52b Delete incompatible Trilogy tests
The trilogy test suite was imported directly, but many of
the test can't work as is in Rails test suite because they were
mutating DB state.

Most are redundant anyway, or should be implemented as shared test
that are executed for all adapters.
2023-04-24 09:35:28 +02:00
fatkodima
b81e98ca44 Fix a deprecation in referential_integrity_test.rb file 2023-04-24 02:11:36 +03:00
Alex Ghiculescu
c363334ddf Fix Marshal.dump on records that use AR Encryption
Fixes https://github.com/rails/rails/issues/48038

I don't think we need to use a proc here - it doesn't seem like there is any performance benefit in doing so. The default is being read from the `columns_hash`, which will already be loaded in memory. And then the `default` method is just reading a scalar value (or returning nil).
2023-04-23 15:49:15 -06:00
fatkodima
a831fed435 Return INCLUDE columns in PostgreSQL indexes as strings 2023-04-23 21:25:52 +03:00
Jean Boussier
8935db5458 TrilogyAdapterTest: use the proper config 2023-04-22 16:04:32 +02:00
Petrik de Heus
0d02e5d4c3
Merge pull request #48022 from p8/docs/fix-header-level
Fix header level for ActiveModel::Naming and DelegatedType
2023-04-22 12:08:52 +02:00
Petrik
2d1ec4bf09 Add more missing headers to Active Record docs [ci-skip] 2023-04-22 11:58:15 +02:00
Petrik
17b3e05133 Fix header level for ActiveModel::Naming and DelegatedType
A class should have a h1 instead of a h2.
2023-04-22 11:25:27 +02:00
Guillermo Iguaran
5beb0621fc
Merge pull request #48012 from fatkodima/mysql-adapter-load-hook
Add load hook for `ActiveRecord::ConnectionAdapters::Mysql2Adapter`
2023-04-21 15:56:16 -07:00
eileencodes
58a0a52019
Fix config and copy over trilogy schema
We had a mysql2_specific_schema.rb file but not one for trilogy that was
causing tests to break. I also removed the prepared statements from
trilogy because it is not supported.
2023-04-21 17:33:25 -04:00
eileencodes
7572a13af6
Raise an error if the connection name doesn't match the adapter
This will prevent us from accidentally running mysql2 tests against
trilogy adapter as we currently are doing.
2023-04-21 17:33:25 -04:00
eileencodes
756cea1b6d
Fix database configuration and generation
I tried using the same config for mysql2 and trilogy but instead it
eneded up breaking the trilogy tests - they were only running in mysql2
mode. I wanted to do this so that the rake tasks for trilogy wouldn't
need to be duplicated but since that didn't work out quite right, I've
decide to duplicate the calls and add if exists / if not exists where
applicable. The configs should be the same but this will make sure that
if they do deviate, the dbs are always created/dropped.
2023-04-21 17:33:24 -04:00
Rafael Mendonça França
484dcb6538
Merge pull request #47648 from fatkodima/internal-options-migrations-logging
Do not log internal options when running migrations
2023-04-21 17:30:08 -04:00
fatkodima
00b8ce6fe5 Add load hook for ActiveRecord::ConnectionAdapters::Mysql2Adapter 2023-04-21 22:00:39 +03:00
Petrik
7723795486 Add some missing headers to Active Records docs [ci-skip]
Having a h1 heading will improve SEO and makes things look more consistent.
2023-04-21 11:09:34 +02:00
Jean Boussier
410d098cb1
Merge pull request #47990 from ghiculescu/verify-fk-reason
Show reason for foreign key error when loading fixtures
2023-04-20 23:39:42 +02:00
Eileen M. Uchitelle
d8a8df3d85
Merge pull request #47996 from Shopify/pm/cpk-query-by-single-record
Extend query-association interface for composite models
2023-04-20 08:35:21 -04:00
Paarth Madan
45da2cfc90 Eager evaluate relation in composite case
Normally, it's valid syntax to pass the predicate builder a mapping from
primary key to a record, to an id, or to a relation.

With the composite case, there's a limitation on the types of syntax
supported. Namely, the only case we support right now is mapping a tuple
of columns to a tuple of corresponding values. For now, it's sufficient
to extract the ids instead of evaluating the SQL at a later time.
2023-04-19 19:22:11 -04:00
Alex Ghiculescu
1f3294421f Show reason for foreign key error when loading fixtures
https://github.com/rails/rails/pull/42674 added the ability to have Rails verify foreign keys when creating fixtures. Feedback from users since then is it would be handy to know *which* foreign keys are being violated. See https://github.com/rails/rails/pull/44943 and https://github.com/rails/rails/pull/47780 for attempts to fix this.

This PR rolls up some of the ideas from those PRs into one that's hopefully mergable.

- [x] `all_foreign_keys_valid?` is deprecated in favour of `check_all_foreign_keys_valid!`.
- [x] Postgres and Sqlite adapters raise an error with detail about the foreign key error.
- [x] Authors of other PRs added as co-authors here to get credit.
- [x] Deprecations updated to work with new deprecation APIs.
- [x] Tests updated.

Here's what the error messages will now look like.

Postgres:

```
Foreign key violations found in your fixture data. Ensure you aren't referring to labels that don't exist on associations. Error from database:

PG::ForeignKeyViolation: ERROR:  insert or update on table "fk_pointing_to_non_existent_objects" violates foreign key constraint "fk_that_will_be_broken"
DETAIL:  Key (fk_object_to_point_to_id)=(980190962) is not present in table "fk_object_to_point_tos".
CONTEXT:  SQL statement "UPDATE pg_constraint SET convalidated=false WHERE conname = 'fk_that_will_be_broken' AND connamespace::regnamespace = 'public'::regnamespace; ALTER TABLE public.fk_pointing_to_non_existent_objects VALIDATE CONSTRAINT fk_that_will_be_broken;"
PL/pgSQL function inline_code_block line 16 at EXECUTE
```

Sqlite:
```
Foreign key violations found in your fixture data. Ensure you aren't referring to labels that don't exist on associations. Error from database:

Foreign key violations found: fk_pointing_to_non_existent_objects
```

Closes https://github.com/rails/rails/pull/47780
Closes https://github.com/rails/rails/pull/44943

Co-Authored-By: s-mage <s-mage@users.noreply.github.com>
Co-Authored-By: danini-the-panini <danini-the-panini@users.noreply.github.com>
2023-04-19 15:36:18 -06:00
Paarth Madan
adf09db3e9 CPK: Fix specifying single record in association
Single records in CPK contexts will take on an array to represent their
identifier. This was problematic because if only a single record is
passed, it's hard to distinguish the behaviour between a list of
multiple primary keys or a list representing a single primary key. As
such, it's helpful to always wrap the result of the single ID in an array,
so as to disambiguate the cases and create consistency in the shape of
the id structure.
2023-04-19 15:49:19 -04:00
Nikita Vasilevsky
cce2a18eb9
[Tests only] Add coverage for .count calculations for a CPK model 2023-04-19 18:29:45 +00:00
Yasuo Honda
f7b56f97fd
Merge pull request #47971 from alpaca-tc/add_support_using_keyword_for_unique_constraint
Adds support `USING INDEX` for unique constraints in PostgreSQL.
2023-04-19 16:39:43 +09:00
alpaca-tc
f5c1222660 Adds support USING INDEX for unique constraints in PostgreSQL.
Adds `:using_index` option to use an existing index when defining a unique constraint.
If you want to change an existing unique index to deferrable, you can use :using_index to create deferrable unique constraints.

```ruby
add_unique_key :users, deferrable: :immediate, using_index: 'unique_index_name'
```

A unique constraint internally constructs a unique index.
If an existing unique index has already been created, the unique constraint
can be created much faster, since there is no need to create the unique index
when generating the constraint.
2023-04-19 13:48:09 +09:00
Eileen M. Uchitelle
d36fb6526b
Merge pull request #47979 from Shopify/pm/cpk-primary-key
Extend primary key methods to support composite keys
2023-04-18 17:27:26 -04:00
eileencodes
6577e8b1e1
Revert "Merge pull request #47864 from zenspider/zenspider/ar_core_hash"
This reverts commit 2815cb96207172f675a49860666f26167757f93c, reversing
changes made to 11a5e3771570f05cb888326765561d4cacbcac5a.

The change broke application code and if we are going to make this
change we will need to deprecate the prior behavior. See #47864 for more
details.
2023-04-18 17:23:45 -04:00
Paarth Madan
6ea0e9182d Extend primary key methods to support composite keys
Let's consider the cases when primary key is composite for these
methods, as this interface ends up being used in many codepaths across
Rails.
2023-04-18 17:01:32 -04:00
Eileen M. Uchitelle
45b4917f21
Merge pull request #47968 from Shopify/pm/uniqueness-validation-cpk
Fix uniqueness validation, #id_in_database can be composite
2023-04-18 14:43:29 -04:00
Paarth Madan
4896b6c0c0 Fix uniqueness validation, #id_in_database can be composite
Until now, specifying uniqueness validations for records that have a composite key fail. This is because uniqueness validation relies on #id_in_database, which didn't yet consider the case when primary key is an array.
2023-04-18 13:52:54 -04:00
Vladimir Dementyev
92bb466dde
Support using CTE names in left_outer_joins 2023-04-18 12:24:50 -04:00
Vladimir Dementyev
3947773022
Add #select_named_joins wrapping #select_association_list to handle CTEs in joins 2023-04-18 11:33:06 -04:00
Vladimir Dementyev
bb1ef9800e
Add CTE support for joins 2023-04-18 11:33:06 -04:00
Adrianna Chang
43f03ea949
Use Trilogy#discard! when discard! called on TrilogyAdapter 2023-04-18 09:19:13 -04:00
Jean Boussier
7239ec1514
Merge pull request #47972 from Shopify/ar-get-version-schema-cache
Active Record: assign connection pool before checking version
2023-04-18 14:38:12 +02:00
Jean Boussier
f8311110fe Active Record: assign connection pool before checking version
`connection.check_version` will emit a query if it doesn't have
a connection pool on which to grab a SchemaCache.
2023-04-18 14:23:14 +02:00
Eileen M. Uchitelle
f7a40229e3
Merge pull request #47880 from adrianna-chang-shopify/ac-trilogy-adapter
Introduce adapter for Trilogy, a MySQL-compatible DB client
2023-04-17 14:56:49 -04:00
Jonathan Hefner
a2a6331451 Add ActiveSupport::MessagePack
`ActiveSupport::MessagePack` is a serializer that integrates with the
`msgpack` gem to serialize a variety of Ruby objects.  `AS::MessagePack`
supports several types beyond the base types that `msgpack` supports,
including `Time` and `Range`, as well as Active Support types such as
`AS::TimeWithZone` and `AS::HashWithIndifferentAccess`.

Compared to `JSON` and `Marshal`, `AS::MessagePack` can provide a
performance improvement and message size reduction.  For example, when
used with `MessageVerifier`:

  ```ruby
  # frozen_string_literal: true

  require "benchmark/ips"
  require "active_support/all"
  require "active_support/message_pack"

  marshal_verifier = ActiveSupport::MessageVerifier.new("secret", serializer: Marshal)
  json_verifier = ActiveSupport::MessageVerifier.new("secret", serializer: JSON)
  asjson_verifier = ActiveSupport::MessageVerifier.new("secret", serializer: ActiveSupport::JSON)
  msgpack_verifier = ActiveSupport::MessageVerifier.new("secret", serializer: ActiveSupport::MessagePack)

  ActiveSupport::Messages::Metadata.use_message_serializer_for_metadata = true
  expiry = 1.year.from_now
  data = { bool: true, num: 123456789, string: "x" * 50 }

  Benchmark.ips do |x|
    x.report("Marshal") do
      marshal_verifier.verify(marshal_verifier.generate(data, expires_at: expiry))
    end

    x.report("JSON") do
      json_verifier.verify(json_verifier.generate(data, expires_at: expiry))
    end

    x.report("AS::JSON") do
      asjson_verifier.verify(asjson_verifier.generate(data, expires_at: expiry))
    end

    x.report("MessagePack") do
      msgpack_verifier.verify(msgpack_verifier.generate(data, expires_at: expiry))
    end

    x.compare!
  end

  puts "Marshal size: #{marshal_verifier.generate(data, expires_at: expiry).bytesize}"
  puts "JSON size: #{json_verifier.generate(data, expires_at: expiry).bytesize}"
  puts "MessagePack size: #{msgpack_verifier.generate(data, expires_at: expiry).bytesize}"
  ```

  ```
  Warming up --------------------------------------
               Marshal     1.206k i/100ms
                  JSON     1.165k i/100ms
              AS::JSON   790.000  i/100ms
           MessagePack     1.798k i/100ms
  Calculating -------------------------------------
               Marshal     11.748k (± 1.3%) i/s -     59.094k in   5.031071s
                  JSON     11.498k (± 1.4%) i/s -     58.250k in   5.066957s
              AS::JSON      7.867k (± 2.4%) i/s -     39.500k in   5.024055s
           MessagePack     17.865k (± 0.8%) i/s -     89.900k in   5.032592s

  Comparison:
           MessagePack:    17864.9 i/s
               Marshal:    11747.8 i/s - 1.52x  (± 0.00) slower
                  JSON:    11498.4 i/s - 1.55x  (± 0.00) slower
              AS::JSON:     7866.9 i/s - 2.27x  (± 0.00) slower

  Marshal size: 254
  JSON size: 234
  MessagePack size: 194
  ```

Additionally, `ActiveSupport::MessagePack::CacheSerializer` is a
serializer that is suitable for use as an `ActiveSupport::Cache` coder.
`AS::MessagePack::CacheSerializer` can serialize `ActiveRecord::Base`
instances, including loaded associations.  Like `AS::MessagePack`, it
provides a performance improvement and payload size reduction:

  ```ruby
  # frozen_string_literal: true

  require "benchmark/ips"
  require "active_support/message_pack"

  ActiveRecord::Base.establish_connection(adapter: "sqlite3", database: ":memory:")

  ActiveRecord::Schema.define do
    create_table :posts, force: true do |t|
      t.string :body
      t.timestamps
    end

    create_table :comments, force: true do |t|
      t.integer :post_id
      t.string :body
      t.timestamps
    end
  end

  class Post < ActiveRecord::Base
    has_many :comments
  end

  class Comment < ActiveRecord::Base
    belongs_to :post
  end

  post = Post.create!(body: "x" * 100)
  2.times { post.comments.create!(body: "x" * 100) }
  post.comments.load
  cache_entry = ActiveSupport::Cache::Entry.new(post)

  Rails70Coder = ActiveSupport::Cache::Coders::Rails70Coder
  CacheSerializer = ActiveSupport::MessagePack::CacheSerializer

  Benchmark.ips do |x|
    x.report("Rails70Coder") do
      Rails70Coder.load(Rails70Coder.dump(cache_entry))
    end

    x.report("CacheSerializer") do
      CacheSerializer.load(CacheSerializer.dump(cache_entry))
    end

    x.compare!
  end

  puts "Rails70Coder size: #{Rails70Coder.dump(cache_entry).bytesize}"
  puts "CacheSerializer size: #{CacheSerializer.dump(cache_entry).bytesize}"
  ```

  ```
  Warming up --------------------------------------
          Rails70Coder   329.000  i/100ms
       CacheSerializer   492.000  i/100ms
  Calculating -------------------------------------
          Rails70Coder      3.285k (± 1.7%) i/s -     16.450k in   5.008447s
       CacheSerializer      4.895k (± 2.4%) i/s -     24.600k in   5.028803s

  Comparison:
       CacheSerializer:     4894.7 i/s
          Rails70Coder:     3285.4 i/s - 1.49x  slower

  Rails70Coder size: 808
  CacheSerializer size: 593
  ```

Co-authored-by: Jean Boussier <jean.boussier@gmail.com>
2023-04-17 11:56:06 -05:00
Adrianna Chang
5ed3f60df6
Introduce adapter for Trilogy, a MySQL-compatible DB client
The [Trilogy database client][trilogy-client] and corresponding
[Active Record adapter][ar-adapter] were both open sourced by GitHub last year.

Shopify has recently taken the plunge and successfully adopted Trilogy in their Rails monolith.
With two major Rails applications running Trilogy successfully, we'd like to propose upstreaming the adapter
to Rails as a MySQL-compatible alternative to Mysql2Adapter.

[trilogy-client]: https://github.com/github/trilogy
[ar-adapter]: https://github.com/github/activerecord-trilogy-adapter

Co-authored-by: Aaron Patterson <tenderlove@github.com>
Co-authored-by: Adam Roben <adam@roben.org>
Co-authored-by: Ali Ibrahim <aibrahim2k2@gmail.com>
Co-authored-by: Aman Gupta <aman@tmm1.net>
Co-authored-by: Arthur Nogueira Neves <github@arthurnn.com>
Co-authored-by: Arthur Schreiber <arthurschreiber@github.com>
Co-authored-by: Ashe Connor <kivikakk@github.com>
Co-authored-by: Brandon Keepers <brandon@opensoul.org>
Co-authored-by: Brian Lopez <seniorlopez@gmail.com>
Co-authored-by: Brooke Kuhlmann <brooke@testdouble.com>
Co-authored-by: Bryana Knight <bryanaknight@github.com>
Co-authored-by: Carl Brasic <brasic@github.com>
Co-authored-by: Chris Bloom <chrisbloom7@github.com>
Co-authored-by: Cliff Pruitt <cliff.pruitt@cliffpruitt.com>
Co-authored-by: Daniel Colson <composerinteralia@github.com>
Co-authored-by: David Calavera <david.calavera@gmail.com>
Co-authored-by: David Celis <davidcelis@github.com>
Co-authored-by: David Ratajczak <david@mockra.com>
Co-authored-by: Dirkjan Bussink <d.bussink@gmail.com>
Co-authored-by: Eileen Uchitelle <eileencodes@gmail.com>
Co-authored-by: Enrique Gonzalez <enriikke@gmail.com>
Co-authored-by: Garrett Bjerkhoel <garrett@github.com>
Co-authored-by: Georgi Knox <georgicodes@github.com>
Co-authored-by: HParker <HParker@github.com>
Co-authored-by: Hailey Somerville <hailey@hailey.lol>
Co-authored-by: James Dennes <jdennes@gmail.com>
Co-authored-by: Jane Sternbach <janester@github.com>
Co-authored-by: Jess Bees <toomanybees@github.com>
Co-authored-by: Jesse Toth <jesse.toth@github.com>
Co-authored-by: Joel Hawksley <joelhawksley@github.com>
Co-authored-by: John Barnette <jbarnette@github.com>
Co-authored-by: John Crepezzi <john.crepezzi@gmail.com>
Co-authored-by: John Hawthorn <john@hawthorn.email>
Co-authored-by: John Nunemaker <nunemaker@gmail.com>
Co-authored-by: Jonathan Hoyt <hoyt@github.com>
Co-authored-by: Katrina Owen <kytrinyx@github.com>
Co-authored-by: Keeran Raj Hawoldar <keeran@gmail.com>
Co-authored-by: Kevin Solorio <soloriok@gmail.com>
Co-authored-by: Leo Correa <lcorr005@gmail.com>
Co-authored-by: Lizz Hale <lizzhale@github.com>
Co-authored-by: Lorin Thwaits <lorint@gmail.com>
Co-authored-by: Matt Jones <al2o3cr@gmail.com>
Co-authored-by: Matthew Draper <matthewd@github.com>
Co-authored-by: Max Veytsman <mveytsman@github.com>
Co-authored-by: Nathan Witmer <nathan@zerowidth.com>
Co-authored-by: Nick Holden <nick.r.holden@gmail.com>
Co-authored-by: Paarth Madan <paarth.madan@shopify.com>
Co-authored-by: Patrick Reynolds <patrick.reynolds@github.com>
Co-authored-by: Rob Sanheim <rsanheim@gmail.com>
Co-authored-by: Rocio Delgado <rocio@github.com>
Co-authored-by: Sam Lambert <sam.lambert@github.com>
Co-authored-by: Shay Frendt <shay@github.com>
Co-authored-by: Shlomi Noach <shlomi-noach@github.com>
Co-authored-by: Sophie Haskins <sophaskins@github.com>
Co-authored-by: Thomas Maurer <tma@github.com>
Co-authored-by: Tim Pease <tim.pease@gmail.com>
Co-authored-by: Yossef Mendelssohn <ymendel@pobox.com>
Co-authored-by: Zack Koppert <zkoppert@github.com>
Co-authored-by: Zhongying Qiao <cryptoque@users.noreply.github.com>
2023-04-17 11:49:07 -04:00
Shozo Hatta
950ffb93d7
Docs: fix misspel on association_basics.md [ci-skip] (#47958)
* Docs: fix misspel on association_basics.md [ci-skip]

* Fix the same misspell on has_one_associations_test.rb
2023-04-17 15:27:23 +09:00
Jean Boussier
325dd7befd
Merge pull request #47948 from fatkodima/rails-5-2-create_table-duplicate-columns
Restore ability to redefine column in `create_table` for Rails 5.2
2023-04-16 13:27:10 +02:00
Jon Dufresne
38ee087262 Fix typo: has -> hash 2023-04-15 07:28:33 -07:00
Eileen M. Uchitelle
881ea9db87
Merge pull request #47947 from Shopify/pm/fixtures-with-composite-key
Support building fixtures with associations that use CPK
2023-04-15 08:12:26 -04:00
Wagner Narde
6f8b5f8a89
Adds documentation for the FixtureSet#identify when the identifier is a UUID 2023-04-14 19:32:16 -03:00
Paarth Madan
3d820195a0 Support fixture associations for composite models
Most of the support here is in implementing how to correctly substitute
multiple values in place of one, for composite caes. In composite cases,
it's not sufficient to hash a label into a single integer value.
Instead, we build an API that accepts a single label, and a list of
columns that we'd like to map to. The algorithm used internally is very
similar to #identify, with an additional bit shift and modulo to cycle
the hash and ensure it doesn't exceed a max.
2023-04-14 18:12:18 -04:00
fatkodima
11aaa3db6c Restore ability to redefine column in create_table for Rails 5.2 2023-04-15 00:32:12 +03:00
sampatbadhe
5c79b0af2d Correct SQL query in where.not docs [ci skip] 2023-04-14 20:46:24 +05:30
fatkodima
a7e7e91e04 Remove table alias added when using where.missing or where.associated 2023-04-14 01:40:41 +03:00
fatkodima
c8438fa998 Require missing CPK models in base_test.rb and calculations_test.rb 2023-04-13 19:49:16 +03:00
Eileen M. Uchitelle
1d7f4e65d6
Merge pull request #47928 from Shopify/pm/cpk-delete
Support deleting records from associations for CPK
2023-04-13 08:53:57 -04:00
Jodh Singh
98e39b8a1b
fixed comment for example sql statement
Ref issue:
https://github.com/rails/rails/issues/47903
2023-04-12 18:07:59 -04:00
Paarth Madan
6afc035cbc Support deleting records from associations for CPK 2023-04-12 17:53:20 -04:00
Eileen M. Uchitelle
385903754e
Merge pull request #47925 from eileencodes/ensure-ids_writer-and-ids_reader-accomodate-cpk
Ensure that ids_writer and ids_reader is working for CPK
2023-04-12 16:21:24 -04:00