File tree Expand file tree Collapse file tree 4 files changed +126
-2
lines changed
spec/active_record/connection_adapters Expand file tree Collapse file tree 4 files changed +126
-2
lines changed Original file line number Diff line number Diff line change @@ -86,6 +86,48 @@ def visit_Arel_Nodes_Except(o, collector)
8686 collector << " )"
8787 end
8888
89+ ##
90+ # To avoid ORA-01795: maximum number of expressions in a list is 1000
91+ # tell ActiveRecord to limit us to 1000 ids at a time
92+ def visit_Arel_Nodes_HomogeneousIn ( o , collector )
93+ in_clause_length = @connection . in_clause_length
94+ values = o . casted_values . map { |v | @connection . quote ( v ) }
95+ column_name = quote_table_name ( o . table_name ) + "." + quote_column_name ( o . column_name )
96+ operator =
97+ if o . type == :in
98+ "IN ("
99+ else
100+ "NOT IN ("
101+ end
102+
103+ if !Array === values || values . length <= in_clause_length
104+ collector << column_name
105+ collector << operator
106+
107+ expr =
108+ if values . empty?
109+ @connection . quote ( nil )
110+ else
111+ values . join ( "," )
112+ end
113+
114+ collector << expr
115+ collector << ")"
116+ else
117+ collector << "("
118+ values . each_slice ( in_clause_length ) . each_with_index do |valuez , i |
119+ collector << " OR " unless i == 0
120+ collector << column_name
121+ collector << operator
122+ collector << valuez . join ( "," )
123+ collector << ")"
124+ end
125+ collector << ")"
126+ end
127+
128+ collector
129+ end
130+
89131 def visit_Arel_Nodes_In ( o , collector )
90132 attr , values = o . left , o . right
91133
Original file line number Diff line number Diff line change @@ -39,6 +39,48 @@ def visit_Arel_Nodes_Except(o, collector)
3939 collector << " )"
4040 end
4141
42+ ##
43+ # To avoid ORA-01795: maximum number of expressions in a list is 1000
44+ # tell ActiveRecord to limit us to 1000 ids at a time
45+ def visit_Arel_Nodes_HomogeneousIn ( o , collector )
46+ in_clause_length = @connection . in_clause_length
47+ values = o . casted_values . map { |v | @connection . quote ( v ) }
48+ column_name = quote_table_name ( o . table_name ) + "." + quote_column_name ( o . column_name )
49+ operator =
50+ if o . type == :in
51+ "IN ("
52+ else
53+ "NOT IN ("
54+ end
55+
56+ if !Array === values || values . length <= in_clause_length
57+ collector << column_name
58+ collector << operator
59+
60+ expr =
61+ if values . empty?
62+ @connection . quote ( nil )
63+ else
64+ values . join ( "," )
65+ end
66+
67+ collector << expr
68+ collector << ")"
69+ else
70+ collector << "("
71+ values . each_slice ( in_clause_length ) . each_with_index do |valuez , i |
72+ collector << " OR " unless i == 0
73+ collector << column_name
74+ collector << operator
75+ collector << valuez . join ( "," )
76+ collector << ")"
77+ end
78+ collector << ")"
79+ end
80+
81+ collector
82+ end
83+
4284 def visit_Arel_Nodes_In ( o , collector )
4385 attr , values = o . left , o . right
4486
Original file line number Diff line number Diff line change 8181 expect ( ActiveRecord ::Base . connection ) . to be_active
8282 end
8383
84- it "should swith to specified schema" do
84+ it "should switch to specified schema" do
8585 ActiveRecord ::Base . establish_connection ( CONNECTION_WITH_SCHEMA_PARAMS )
8686 expect ( ActiveRecord ::Base . connection . current_schema ) . to eq ( CONNECTION_WITH_SCHEMA_PARAMS [ :schema ] . upcase )
8787 expect ( ActiveRecord ::Base . connection . current_user ) . to eq ( CONNECTION_WITH_SCHEMA_PARAMS [ :username ] . upcase )
8888 end
8989
90- it "should swith to specified schema after reset" do
90+ it "should switch to specified schema after reset" do
9191 ActiveRecord ::Base . connection . reset!
9292 expect ( ActiveRecord ::Base . connection . current_schema ) . to eq ( CONNECTION_WITH_SCHEMA_PARAMS [ :schema ] . upcase )
9393 end
Original file line number Diff line number Diff line change @@ -193,6 +193,46 @@ class ::TestComment < ActiveRecord::Base
193193 end
194194 end
195195
196+ describe "lists" do
197+ before ( :all ) do
198+ schema_define do
199+ create_table :test_posts do |t |
200+ t . string :title
201+ end
202+ end
203+ class ::TestPost < ActiveRecord ::Base
204+ has_many :test_comments
205+ end
206+ @ids = ( 1 ..1010 ) . to_a
207+ TestPost . transaction do
208+ @ids . each do |id |
209+ TestPost . create! ( id : id , title : "Title #{ id } " )
210+ end
211+ end
212+ end
213+
214+ after ( :all ) do
215+ schema_define do
216+ drop_table :test_posts
217+ end
218+ Object . send ( :remove_const , "TestPost" )
219+ ActiveRecord ::Base . clear_cache!
220+ end
221+
222+ ##
223+ # See this GitHub issue for an explanation of homogenous lists.
224+ # https://github.com/rails/rails/commit/72fd0bae5948c1169411941aeea6fef4c58f34a9
225+ it "should allow more than 1000 items in a list where the list is homogenous" do
226+ posts = TestPost . where ( id : @ids ) . to_a
227+ expect ( posts . size ) . to eq ( @ids . size )
228+ end
229+
230+ it "should allow more than 1000 items in a list where the list is non-homogenous" do
231+ posts = TestPost . where ( id : [ *@ids , nil ] ) . to_a
232+ expect ( posts . size ) . to eq ( @ids . size )
233+ end
234+ end
235+
196236 describe "with statement pool" do
197237 before ( :all ) do
198238 ActiveRecord ::Base . establish_connection ( CONNECTION_PARAMS . merge ( statement_limit : 3 ) )
You can’t perform that action at this time.
0 commit comments