Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Various fixes #1040

Merged
merged 6 commits into from
Dec 4, 2019
Merged

Various fixes #1040

merged 6 commits into from
Dec 4, 2019

Conversation

dr-itz
Copy link
Contributor

@dr-itz dr-itz commented Nov 10, 2019

This is mainly some "fallout" from ongoing work for Rails 6.1 (i.e. master) support

This helps debugging stuff that only fails when run in combination.
When a wrong URL is provided, it can happen that newConnection() returns
null. If this happens during configure_connection, the whole process is
called over and over again and results in a stack overflow.
Instead, just throw an error.

Noticed because a new test in Rails master tries to connect with
"mysql2:///wait_timeout=60", an URL unknown to JDBC.
AR tests do things like:
  ActiveRecord::Base.configurations["arunit"].merge(database: "inexistent_activerecord_unittest")
which is also valid in applications. Not dup'ing the config is problematic:
E.g. the mysql adapter has this (simplified):

  unless config[:url]
    config[:url] = "...#{config[:database]}"
  end

So once a DB connection has been made with the original config, :url is
set, above example that tries a different DB has no effect at all and
gives a connection the the original database instead. Fun.

.deep_dup solves the problem as the original config is left untouched.
@enebo
Copy link
Member

enebo commented Nov 11, 2019

@dr-itz so these changes work all the way back to 5.0 but will minimize our diff for when 6.1 comes? Also do you think we should create 60-stable yet?

@dr-itz
Copy link
Contributor Author

dr-itz commented Nov 11, 2019

@enebo that deep_dup thing is an actual bug fix. Other people have seen this, also there is #954. Yes, a 60-stable would be appreciated once this thing is in and hits master.

There have been some API changes, so 60.x doesn't work anymore on Rails master.

@dr-itz dr-itz mentioned this pull request Nov 25, 2019
Copy link
Member

@enebo enebo left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks ok to me but I will ask one question: Do we care that execute_insert has changed arity? In JRuby, proper I would say this is too risky but is the Java of arjdbc an API for external consumption?

We should play it safe and maintain original signature and pass context.nil for pk to the newer signature.

@dr-itz
Copy link
Contributor Author

dr-itz commented Dec 3, 2019

Looks ok to me but I will ask one question: Do we care that execute_insert has changed arity? In JRuby, proper I would say this is too risky but is the Java of arjdbc an API for external consumption?

I'd say we shouldn't care too much since this is an API between the ruby and the java part...sure you can access it, but...

We should play it safe and maintain original signature and pass context.nil for pk to the newer signature.

you lost me there. where do you mean?

@dr-itz
Copy link
Contributor Author

dr-itz commented Dec 3, 2019

whoos, just notices this indented with tabs instead of spaces..will fix

JDBC offers an API to specify what keys to return. Rails knows the keys.
Use that API directly to avoid loading too much data. E.g. pgjdbc
appends "RETURNING *" to an insert query, effectively return _all_
columns. Since the jdbc driver does that, nobody ever noticed that
the PG adapter is missing the code that appends the `RETURNING <pk>`
@enebo
Copy link
Member

enebo commented Dec 3, 2019

@deprecated
 @JRubyMethod(name = "execute_insert", required = 1)
    public IRubyObject execute_insert(final ThreadContext context, final IRubyObject sql) {
return execute_insert(context, sql, context.nil);
}

The only reason is if any existing external gem is using arjdbc as a transitive dep it will get an error. I suppose the question to ask is this change so needed that we should break an existing gem (if one actually exists)?

@dr-itz
Copy link
Contributor Author

dr-itz commented Dec 3, 2019

Ah now I get it. Makes a lot of sense, but we need to rename the new signature because there's the version with binds too. So old we had required = 1/2 and new we have required = 2/3 having an overlap there. Pushed on top

@enebo
Copy link
Member

enebo commented Dec 3, 2019

@dr-itz looks fine to me now but I defer to @kares in case he realizes something I do not.

@dr-itz
Copy link
Contributor Author

dr-itz commented Dec 3, 2019

@enebo thanks

@dr-itz
Copy link
Contributor Author

dr-itz commented Dec 4, 2019

Something‘s going on with mariadb in CI...i‘ll check tomorrow if it‘s related

@@ -96,7 +96,7 @@ def initialize; end
connection_handler = connection_handler_stub

config = { :jndi => 'jdbc/TestDS' }
connection_handler.expects(:jndi_connection)
connection_handler.expects(:jndi_connection).with() { |c| config = c }
Copy link
Member

@kares kares Dec 4, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

just a minor thingy ... (its morning here) but did you not mean config == c ? 🍰

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nope. Since config is now cloned in the connection handler, we cannot check for changes on the original object. By catching the jndi_connection arg I can get the cloned and changed object out this way. It's a bit ugly but it was the easiest way I could come up with

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ooh so that is what this accomplishes, thanks!

@kares kares self-requested a review December 4, 2019 08:28
Copy link
Member

@kares kares left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Rails's exec_insert takes a lot of params so I would not mind adding one on execute_insert to kind of be on "par". initially did not like the exec_insert_pk naming that much (if its something possibly to be used outside as an API) but checking Rails API I did not come up with anything better ... so fine by me.

@dr-itz
Copy link
Contributor Author

dr-itz commented Dec 4, 2019

Something‘s going on with mariadb in CI...i‘ll check tomorrow if it‘s related

ok, it's pre-existing. I'll look into it maybe over the weekend :)

@enebo enebo merged commit 732c838 into jruby:50-stable Dec 4, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants