mirror of https://github.com/rails/rails
Fix cases where CTE's are not supported
CTE's are not supported for MySQL versions below 8.0, so these tests were failing locally for me on MySQL 5.7. While 5.7 is quite old, it's still supported and used by many major Rails applications and we need a check for support in our tests. In addition to this PR I'll need to get a buildkite build running for 5.7. This wasn't caught earlier because our buildkite upgraded to 8.0.
This commit is contained in:
parent
05ae3faaf3
commit
3c7e190ee8
|
@ -326,6 +326,9 @@ module ActiveRecord
|
|||
|
||||
# Add a Common Table Expression (CTE) that you can then reference within another SELECT statement.
|
||||
#
|
||||
# Note: CTE's are only supported in MySQL for versions 8.0 and above. You will not be able to
|
||||
# use CTE's with MySQL 5.7.
|
||||
#
|
||||
# Post.with(posts_with_tags: Post.where("tags_count > ?", 0))
|
||||
# # => ActiveRecord::Relation
|
||||
# # WITH posts_with_tags AS (
|
||||
|
|
|
@ -394,30 +394,32 @@ class MergingDifferentRelationsTest < ActiveRecord::TestCase
|
|||
assert_equal dev.ratings, [rating_1]
|
||||
end
|
||||
|
||||
test "merging relation with common table expression" do
|
||||
posts_with_tags = Post.with(posts_with_tags: Post.where("tags_count > 0")).from("posts_with_tags AS posts")
|
||||
posts_with_comments = Post.where("legacy_comments_count > 0")
|
||||
relation = posts_with_comments.merge(posts_with_tags).order("posts.id")
|
||||
if ActiveRecord::Base.connection.supports_common_table_expressions?
|
||||
test "merging relation with common table expression" do
|
||||
posts_with_tags = Post.with(posts_with_tags: Post.where("tags_count > 0")).from("posts_with_tags AS posts")
|
||||
posts_with_comments = Post.where("legacy_comments_count > 0")
|
||||
relation = posts_with_comments.merge(posts_with_tags).order("posts.id")
|
||||
|
||||
assert_equal [1, 2, 7], relation.pluck(:id)
|
||||
end
|
||||
assert_equal [1, 2, 7], relation.pluck(:id)
|
||||
end
|
||||
|
||||
test "merging multiple relations with common table expression" do
|
||||
posts_with_tags = Post.with(posts_with_tags: Post.where("tags_count > 0"))
|
||||
posts_with_comments = Post.with(posts_with_comments: Post.where("legacy_comments_count > 0"))
|
||||
relation = posts_with_comments.merge(posts_with_tags)
|
||||
.joins("JOIN posts_with_tags pwt ON pwt.id = posts.id JOIN posts_with_comments pwc ON pwc.id = posts.id").order("posts.id")
|
||||
test "merging multiple relations with common table expression" do
|
||||
posts_with_tags = Post.with(posts_with_tags: Post.where("tags_count > 0"))
|
||||
posts_with_comments = Post.with(posts_with_comments: Post.where("legacy_comments_count > 0"))
|
||||
relation = posts_with_comments.merge(posts_with_tags)
|
||||
.joins("JOIN posts_with_tags pwt ON pwt.id = posts.id JOIN posts_with_comments pwc ON pwc.id = posts.id").order("posts.id")
|
||||
|
||||
assert_equal [1, 2, 7], relation.pluck(:id)
|
||||
end
|
||||
assert_equal [1, 2, 7], relation.pluck(:id)
|
||||
end
|
||||
|
||||
test "relation merger leaves to database to decide what to do when multiple CTEs with same alias are passed" do
|
||||
posts_with_tags = Post.with(popular_posts: Post.where("tags_count > 0"))
|
||||
posts_with_comments = Post.with(popular_posts: Post.where("legacy_comments_count > 0"))
|
||||
relation = posts_with_tags.merge(posts_with_comments).joins("JOIN popular_posts pp ON pp.id = posts.id")
|
||||
test "relation merger leaves to database to decide what to do when multiple CTEs with same alias are passed" do
|
||||
posts_with_tags = Post.with(popular_posts: Post.where("tags_count > 0"))
|
||||
posts_with_comments = Post.with(popular_posts: Post.where("legacy_comments_count > 0"))
|
||||
relation = posts_with_tags.merge(posts_with_comments).joins("JOIN popular_posts pp ON pp.id = posts.id")
|
||||
|
||||
assert_raises ActiveRecord::StatementInvalid do
|
||||
relation.load
|
||||
assert_raises ActiveRecord::StatementInvalid do
|
||||
relation.load
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -15,50 +15,58 @@ module ActiveRecord
|
|||
POSTS_WITH_TAGS_AND_COMMENTS = (POSTS_WITH_COMMENTS & POSTS_WITH_TAGS).sort.freeze
|
||||
POSTS_WITH_TAGS_AND_MULTIPLE_COMMENTS = (POSTS_WITH_MULTIPLE_COMMENTS & POSTS_WITH_TAGS).sort.freeze
|
||||
|
||||
def test_with_when_hash_is_passed_as_an_argument
|
||||
relation = Post
|
||||
.with(posts_with_comments: Post.where("legacy_comments_count > 0"))
|
||||
.from("posts_with_comments AS posts")
|
||||
if ActiveRecord::Base.connection.supports_common_table_expressions?
|
||||
def test_with_when_hash_is_passed_as_an_argument
|
||||
relation = Post
|
||||
.with(posts_with_comments: Post.where("legacy_comments_count > 0"))
|
||||
.from("posts_with_comments AS posts")
|
||||
|
||||
assert_equal POSTS_WITH_COMMENTS, relation.order(:id).pluck(:id)
|
||||
end
|
||||
assert_equal POSTS_WITH_COMMENTS, relation.order(:id).pluck(:id)
|
||||
end
|
||||
|
||||
def test_with_when_hash_with_multiple_elements_of_different_type_is_passed_as_an_argument
|
||||
cte_options = {
|
||||
posts_with_tags: Post.arel_table.project(Arel.star).where(Post.arel_table[:tags_count].gt(0)),
|
||||
posts_with_tags_and_comments: Arel.sql("SELECT * FROM posts_with_tags WHERE legacy_comments_count > 0"),
|
||||
"posts_with_tags_and_multiple_comments" => Post.where("legacy_comments_count > 1").from("posts_with_tags_and_comments AS posts")
|
||||
}
|
||||
relation = Post.with(cte_options).from("posts_with_tags_and_multiple_comments AS posts")
|
||||
def test_with_when_hash_with_multiple_elements_of_different_type_is_passed_as_an_argument
|
||||
cte_options = {
|
||||
posts_with_tags: Post.arel_table.project(Arel.star).where(Post.arel_table[:tags_count].gt(0)),
|
||||
posts_with_tags_and_comments: Arel.sql("SELECT * FROM posts_with_tags WHERE legacy_comments_count > 0"),
|
||||
"posts_with_tags_and_multiple_comments" => Post.where("legacy_comments_count > 1").from("posts_with_tags_and_comments AS posts")
|
||||
}
|
||||
relation = Post.with(cte_options).from("posts_with_tags_and_multiple_comments AS posts")
|
||||
|
||||
assert_equal POSTS_WITH_TAGS_AND_MULTIPLE_COMMENTS, relation.order(:id).pluck(:id)
|
||||
end
|
||||
assert_equal POSTS_WITH_TAGS_AND_MULTIPLE_COMMENTS, relation.order(:id).pluck(:id)
|
||||
end
|
||||
|
||||
def test_multiple_with_calls
|
||||
relation = Post
|
||||
.with(posts_with_tags: Post.where("tags_count > 0"))
|
||||
.from("posts_with_tags_and_comments AS posts")
|
||||
.with(posts_with_tags_and_comments: Arel.sql("SELECT * FROM posts_with_tags WHERE legacy_comments_count > 0"))
|
||||
def test_multiple_with_calls
|
||||
relation = Post
|
||||
.with(posts_with_tags: Post.where("tags_count > 0"))
|
||||
.from("posts_with_tags_and_comments AS posts")
|
||||
.with(posts_with_tags_and_comments: Arel.sql("SELECT * FROM posts_with_tags WHERE legacy_comments_count > 0"))
|
||||
|
||||
assert_equal POSTS_WITH_TAGS_AND_COMMENTS, relation.order(:id).pluck(:id)
|
||||
end
|
||||
assert_equal POSTS_WITH_TAGS_AND_COMMENTS, relation.order(:id).pluck(:id)
|
||||
end
|
||||
|
||||
def test_count_after_with_call
|
||||
relation = Post.with(posts_with_comments: Post.where("legacy_comments_count > 0"))
|
||||
def test_count_after_with_call
|
||||
relation = Post.with(posts_with_comments: Post.where("legacy_comments_count > 0"))
|
||||
|
||||
assert_equal Post.count, relation.count
|
||||
assert_equal POSTS_WITH_COMMENTS.size, relation.from("posts_with_comments AS posts").count
|
||||
assert_equal POSTS_WITH_COMMENTS.size, relation.joins("JOIN posts_with_comments ON posts_with_comments.id = posts.id").count
|
||||
end
|
||||
assert_equal Post.count, relation.count
|
||||
assert_equal POSTS_WITH_COMMENTS.size, relation.from("posts_with_comments AS posts").count
|
||||
assert_equal POSTS_WITH_COMMENTS.size, relation.joins("JOIN posts_with_comments ON posts_with_comments.id = posts.id").count
|
||||
end
|
||||
|
||||
def test_with_when_called_from_active_record_scope
|
||||
assert_equal POSTS_WITH_TAGS, Post.with_tags_cte.order(:id).pluck(:id)
|
||||
end
|
||||
def test_with_when_called_from_active_record_scope
|
||||
assert_equal POSTS_WITH_TAGS, Post.with_tags_cte.order(:id).pluck(:id)
|
||||
end
|
||||
|
||||
def test_with_when_invalid_params_are_passed
|
||||
assert_raise(ArgumentError) { Post.with }
|
||||
assert_raise(ArgumentError) { Post.with(posts_with_tags: nil).load }
|
||||
assert_raise(ArgumentError) { Post.with(posts_with_tags: [Post.where("tags_count > 0")]).load }
|
||||
def test_with_when_invalid_params_are_passed
|
||||
assert_raise(ArgumentError) { Post.with }
|
||||
assert_raise(ArgumentError) { Post.with(posts_with_tags: nil).load }
|
||||
assert_raise(ArgumentError) { Post.with(posts_with_tags: [Post.where("tags_count > 0")]).load }
|
||||
end
|
||||
else
|
||||
def test_common_table_expressions_are_unsupported
|
||||
assert_raises ActiveRecord::StatementInvalid do
|
||||
Post.with_tags_cte.order(:id).pluck(:id)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
Loading…
Reference in New Issue