Created
March 17, 2019 08:37
-
-
Save mattyoho/456cdd5668c30020933b1a55bc991443 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
diff --git a/activerecord/lib/active_record/relation/query_methods.rb b/activerecord/lib/active_record/relation/query_methods.rb | |
index 2955ead3bb..01467628d8 100644 | |
--- a/activerecord/lib/active_record/relation/query_methods.rb | |
+++ b/activerecord/lib/active_record/relation/query_methods.rb | |
@@ -348,7 +348,7 @@ def reorder!(*args) # :nodoc: | |
self | |
end | |
- VALID_UNSCOPING_VALUES = Set.new([:where, :select, :group, :order, :lock, | |
+ VALID_UNSCOPING_VALUES = Set.new([:where, :select, :group, :order, :lock, :optimizer_hints, | |
:limit, :offset, :joins, :left_outer_joins, | |
:includes, :from, :readonly, :having, :annotate]) | |
diff --git a/activerecord/lib/arel/nodes.rb b/activerecord/lib/arel/nodes.rb | |
index 76b51812ed..1e475ac819 100644 | |
--- a/activerecord/lib/arel/nodes.rb | |
+++ b/activerecord/lib/arel/nodes.rb | |
@@ -66,6 +66,7 @@ | |
require "arel/nodes/string_join" | |
require "arel/nodes/annotation" | |
+require "arel/nodes/optimizer_hints" | |
require "arel/nodes/sql_literal" | |
diff --git a/activerecord/lib/arel/nodes/optimizer_hints.rb b/activerecord/lib/arel/nodes/optimizer_hints.rb | |
new file mode 100644 | |
index 0000000000..d1048ccf74 | |
--- /dev/null | |
+++ b/activerecord/lib/arel/nodes/optimizer_hints.rb | |
@@ -0,0 +1,8 @@ | |
+# frozen_string_literal: true | |
+ | |
+module Arel # :nodoc: all | |
+ module Nodes | |
+ class OptimizerHints < Arel::Nodes::Annotation | |
+ end | |
+ end | |
+end | |
diff --git a/activerecord/lib/arel/nodes/unary.rb b/activerecord/lib/arel/nodes/unary.rb | |
index 6d1ac36b0e..00639304e4 100644 | |
--- a/activerecord/lib/arel/nodes/unary.rb | |
+++ b/activerecord/lib/arel/nodes/unary.rb | |
@@ -35,7 +35,6 @@ def eql?(other) | |
Not | |
Offset | |
On | |
- OptimizerHints | |
Ordering | |
RollUp | |
}.each do |name| | |
diff --git a/activerecord/lib/arel/select_manager.rb b/activerecord/lib/arel/select_manager.rb | |
index 2bd7cf8a97..96b1b46452 100644 | |
--- a/activerecord/lib/arel/select_manager.rb | |
+++ b/activerecord/lib/arel/select_manager.rb | |
@@ -148,7 +148,7 @@ def projections=(projections) | |
def optimizer_hints(*hints) | |
unless hints.empty? | |
- @ctx.optimizer_hints = Arel::Nodes::OptimizerHints.new(hints) | |
+ @ctx.optimizer_hints = Arel::Nodes::OptimizerHints.new(*hints) | |
end | |
self | |
end | |
diff --git a/activerecord/lib/arel/visitors/depth_first.rb b/activerecord/lib/arel/visitors/depth_first.rb | |
index bfb5684203..e11f53a24a 100644 | |
--- a/activerecord/lib/arel/visitors/depth_first.rb | |
+++ b/activerecord/lib/arel/visitors/depth_first.rb | |
@@ -35,7 +35,6 @@ def unary(o) | |
alias :visit_Arel_Nodes_Ascending :unary | |
alias :visit_Arel_Nodes_Descending :unary | |
alias :visit_Arel_Nodes_UnqualifiedColumn :unary | |
- alias :visit_Arel_Nodes_OptimizerHints :unary | |
def function(o) | |
visit o.expressions | |
@@ -184,6 +183,7 @@ def visit_Arel_Nodes_UpdateStatement(o) | |
def visit_Arel_Nodes_Annotation(o) | |
visit o.values | |
end | |
+ alias :visit_Arel_Nodes_OptimizerHints :visit_Arel_Nodes_Annotation | |
def visit_Array(o) | |
o.each { |i| visit i } | |
diff --git a/activerecord/lib/arel/visitors/dot.rb b/activerecord/lib/arel/visitors/dot.rb | |
index 157150c16c..c59163d4dd 100644 | |
--- a/activerecord/lib/arel/visitors/dot.rb | |
+++ b/activerecord/lib/arel/visitors/dot.rb | |
@@ -82,7 +82,6 @@ def unary(o) | |
alias :visit_Arel_Nodes_Offset :unary | |
alias :visit_Arel_Nodes_On :unary | |
alias :visit_Arel_Nodes_UnqualifiedColumn :unary | |
- alias :visit_Arel_Nodes_OptimizerHints :unary | |
alias :visit_Arel_Nodes_Preceding :unary | |
alias :visit_Arel_Nodes_Following :unary | |
alias :visit_Arel_Nodes_Rows :unary | |
@@ -237,6 +236,7 @@ def visit_Array(o) | |
def visit_Arel_Nodes_Annotation(o) | |
visit_edge(o, "values") | |
end | |
+ alias :visit_Arel_Nodes_OptimizerHints :visit_Arel_Nodes_Annotation | |
def visit_edge(o, method) | |
edge(method) { visit o.send(method) } | |
diff --git a/activerecord/lib/arel/visitors/ibm_db.rb b/activerecord/lib/arel/visitors/ibm_db.rb | |
index 0ffc0725f7..4ca6f27af9 100644 | |
--- a/activerecord/lib/arel/visitors/ibm_db.rb | |
+++ b/activerecord/lib/arel/visitors/ibm_db.rb | |
@@ -10,7 +10,7 @@ def visit_Arel_Nodes_SelectCore(o, collector) | |
end | |
def visit_Arel_Nodes_OptimizerHints(o, collector) | |
- collector << "/* <OPTGUIDELINES>#{sanitize_as_sql_comment(o).join}</OPTGUIDELINES> */" | |
+ collector << "/* <OPTGUIDELINES>#{o.values.join}</OPTGUIDELINES> */" | |
end | |
def visit_Arel_Nodes_Limit(o, collector) | |
diff --git a/activerecord/lib/arel/visitors/informix.rb b/activerecord/lib/arel/visitors/informix.rb | |
index cd43be8858..63c2a671a9 100644 | |
--- a/activerecord/lib/arel/visitors/informix.rb | |
+++ b/activerecord/lib/arel/visitors/informix.rb | |
@@ -43,7 +43,7 @@ def visit_Arel_Nodes_SelectCore(o, collector) | |
end | |
def visit_Arel_Nodes_OptimizerHints(o, collector) | |
- collector << "/*+ #{sanitize_as_sql_comment(o).join(", ")} */" | |
+ collector << "/*+ #{o.values.join(", ")} */" | |
end | |
def visit_Arel_Nodes_Offset(o, collector) | |
diff --git a/activerecord/lib/arel/visitors/mssql.rb b/activerecord/lib/arel/visitors/mssql.rb | |
index 85815baca2..cc916f5bee 100644 | |
--- a/activerecord/lib/arel/visitors/mssql.rb | |
+++ b/activerecord/lib/arel/visitors/mssql.rb | |
@@ -82,7 +82,7 @@ def visit_Arel_Nodes_SelectCore(o, collector) | |
end | |
def visit_Arel_Nodes_OptimizerHints(o, collector) | |
- collector << "OPTION (#{sanitize_as_sql_comment(o).join(", ")})" | |
+ collector << "OPTION (#{o.values.join(", ")})" | |
end | |
def get_offset_limit_clause(o) | |
diff --git a/activerecord/lib/arel/visitors/to_sql.rb b/activerecord/lib/arel/visitors/to_sql.rb | |
index 0a6d090a82..f31a4aadfb 100644 | |
--- a/activerecord/lib/arel/visitors/to_sql.rb | |
+++ b/activerecord/lib/arel/visitors/to_sql.rb | |
@@ -240,7 +240,7 @@ def visit_Arel_Nodes_SelectCore(o, collector) | |
end | |
def visit_Arel_Nodes_OptimizerHints(o, collector) | |
- collector << "/*+ #{sanitize_as_sql_comment(o).join(" ")} */" | |
+ collector << "/*+ #{o.values.join(SPACE)} */" | |
end | |
def collect_nodes_for(nodes, collector, spacer, connector = COMMA) | |
@@ -810,10 +810,6 @@ def quote_column_name(name) | |
@connection.quote_column_name(name) | |
end | |
- def sanitize_as_sql_comment(o) | |
- o.expr.map { |v| v.gsub(%r{ /\*\+?\s* | \s*\*/ }x, "") } | |
- end | |
- | |
def collect_optimizer_hints(o, collector) | |
maybe_visit o.optimizer_hints, collector | |
end | |
diff --git a/activerecord/test/cases/adapters/mysql2/optimizer_hints_test.rb b/activerecord/test/cases/adapters/mysql2/optimizer_hints_test.rb | |
index 349de49b36..17579e6389 100644 | |
--- a/activerecord/test/cases/adapters/mysql2/optimizer_hints_test.rb | |
+++ b/activerecord/test/cases/adapters/mysql2/optimizer_hints_test.rb | |
@@ -13,12 +13,6 @@ def test_optimizer_hints | |
posts = posts.select(:id).where(author_id: [0, 1]) | |
assert_includes posts.explain, "| index | index_posts_on_author_id | index_posts_on_author_id |" | |
end | |
- | |
- assert_sql(%r{\ASELECT /\*\+ NO_RANGE_OPTIMIZATION\(posts index_posts_on_author_id\) \*/}) do | |
- posts = Post.optimizer_hints("/*+ NO_RANGE_OPTIMIZATION(posts index_posts_on_author_id) */") | |
- posts = posts.select(:id).where(author_id: [0, 1]) | |
- assert_includes posts.explain, "| index | index_posts_on_author_id | index_posts_on_author_id |" | |
- end | |
end | |
end | |
end | |
diff --git a/activerecord/test/cases/adapters/postgresql/optimizer_hints_test.rb b/activerecord/test/cases/adapters/postgresql/optimizer_hints_test.rb | |
index 1bfa815cac..206096e0ff 100644 | |
--- a/activerecord/test/cases/adapters/postgresql/optimizer_hints_test.rb | |
+++ b/activerecord/test/cases/adapters/postgresql/optimizer_hints_test.rb | |
@@ -17,12 +17,6 @@ def test_optimizer_hints | |
posts = posts.select(:id).where(author_id: [0, 1]) | |
assert_includes posts.explain, "Seq Scan on posts" | |
end | |
- | |
- assert_sql(%r{\ASELECT /\*\+ SeqScan\(posts\) \*/}) do | |
- posts = Post.optimizer_hints("/*+ SeqScan(posts) */") | |
- posts = posts.select(:id).where(author_id: [0, 1]) | |
- assert_includes posts.explain, "Seq Scan on posts" | |
- end | |
end | |
end | |
end | |
diff --git a/activerecord/test/cases/relation_test.rb b/activerecord/test/cases/relation_test.rb | |
index 061328df5f..29bfcabbd7 100644 | |
--- a/activerecord/test/cases/relation_test.rb | |
+++ b/activerecord/test/cases/relation_test.rb | |
@@ -355,6 +355,15 @@ def test_relation_without_annotation_does_not_include_an_empty_comment | |
assert_predicate log.select { |query| query.match?(%r{/\*}) }, :empty? | |
end | |
+ def test_relation_with_optimizer_hints_filters_sql_comment_delimiters | |
+ post_with_hint = Post.where(id: 1).optimizer_hints("**//BADHINT//**") | |
+ assert_match %r{BADHINT}, post_with_hint.to_sql | |
+ assert_no_match %r{\*/BADHINT}, post_with_hint.to_sql | |
+ assert_no_match %r{\*//BADHINT}, post_with_hint.to_sql | |
+ assert_no_match %r{BADHINT/\*}, post_with_hint.to_sql | |
+ assert_no_match %r{BADHINT//\*}, post_with_hint.to_sql | |
+ end | |
+ | |
class EnsureRoundTripTypeCasting < ActiveRecord::Type::Value | |
def type | |
:string |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment