When MysqlAdapter.select and
MysqlAdapter.select_rows are used to call a stored
procedure that returns a result set, the connection is left in a
state that expects a further call to check for more results and, if
necessary, to retrieve the next result, even though the desired
result set has already been returned. Failure to tidy up the
connection results in Mysql::Error: Commands out of
sync when the connection is next used. Such a failure can
be seen by calling
ActiveRecord::Base.connection.active? which
returns false, leading one to suspect that the connection was
dropped when in fact the act of calling
ActiveRecord::Base.connection.active? was itself
an out of sync command and was responsible for the dropped
connection. This explains why the current
test_multi_results method in
activerecord/test/cases/adapters/mysql/connection_test.rb
neglects to call @connection.active? in the way
the preceding tests do. My patch adds this call and the test passes
once the problem is fixed.
The bug is easily fixed by adding the single statement that is
commented below.
@connection.query_with_result = true
result = execute(sql, name)
rows = []
result.each_hash { |row| rows << row }
result.free
@connection.more_results && @connection.next_result # invoking stored procedures with CLIENT_MULTI_RESULTS requires this to tidy up else the connection will be dropped
rows
I have provided the fix plus a new test in the attached diff
file.
I posted this more than a week ago under #3151 MySQL adapter update to enable use of stored procedures but it has not yet received attention,
presumably as it has a milestone for 2.3.9 and most people are
focussed on 3.0. I am concerned that this patch should make it to
the 3.0 release.