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
to_sql in Rails 4.2 returns parameterized queries instead of full SQL statements #18379
Comments
BTW, I'm using Postgres 9.3.5 if that matters. |
Guessing this is down to the merge of AdequateRecord and the query caching |
This is not what our maintenance policy say: http://guides.rubyonrails.org/maintenance_policy.html
About If you don't want this behavior you can:
def self.get_my_big_ole_query(some_id)
TableZeroClass.unprepared_statement do
TableZeroClass.
where(id: some_id).
union(
my_other_active_relation.
where(id: some_id),
).
to_sql
end
end |
As of 4.2, it's actually expected to never contain bind variables -- though as @rafaelfranca said, it has historically done so, and we've made no stronger claim that it won't any more. So, while this isn't a bug / breaking change by support policy, we'd probably still like to understand what's going on, and possibly change it. |
👍 maybe I have missed this change to never return bind parameters. On Wed, Jan 7, 2015, 08:18 Matthew Draper notifications@github.com wrote:
|
Right. It is not intended to return with binds
|
First and most importantly, what do you all need from me to help you all track this bug down? 🐛 And in response to your comments: @rafaelfranca I'd thought I'd heard that Rails had started using SemVer. Evidently it's using MarketingVer where the first digit means nothing other than "this is how many times we've released Rails at RailsConf" 😄 @rafaelfranca @matthewd If it was not the case then it would be: User.where(name: 'Oscar').to_sql
# => SELECT "users".* FROM "users" WHERE "users"."name" = $1 If you mean it's not explicitly documented to return only an unparameterized query and therefore it's ok to make it do so, I think that's a poor argument. I'm sure there are a lot of things in the documentation which are not explicit but which are expected by most developers. I think most developers would be surprised that a method called |
@rafaelfranca your proposed solution: def self.get_my_big_ole_query(some_id)
TableZeroClass.unprepared_statement do
TableZeroClass.
where(id: some_id).
union(
my_other_active_relation.
where(id: some_id),
).
to_sql
end
end results in
def self.get_my_big_ole_query(some_id)
TableZeroClass.connection.unprepared_statement do
TableZeroClass.
where(id: some_id).
union(
my_other_active_relation.
where(id: some_id),
).
to_sql
end
end Results in a Even if I pare it down to: def self.get_my_big_ole_query(some_id)
TableZeroClass.connection.unprepared_statement do
TableZeroClass.
where(id: some_id).
to_sql
end
end The |
But getting back to the original problem which is that TableOneClass.
models.
active.
select(
:some_column,
).to_sql and TableZeroClass.
where(id: some_id).
to_sql Each result in an unparameterized query. |
A self-contained reproduction script would be a great start.
This is the type of stuff that wears out OSS maintainers. We should stick to fixing the bug, please.
When did Rails start supporting
So it's behaving as the docs say. |
@jfelchner the most productive path to getting this issue solved would've been for you to skip this comment entirely, I think. Sarcastic mea culpa aside, if you can find any official source that claims Rails uses SemVer, please point it out so we can fix it. I think my meaning was pretty clear: "it has historically done so, and we've made no stronger claim that it won't any more". I think most developers won't expect an instance of one class to conform to the documented API of a different class, from a different library. And you're getting that instance because you're calling a method that's not part of AR's documented API. |
@tenderlove @matthewd the SemVer comment was a joke... hence the smiley. Evidently a poor one from your perspective. I should have understood in the context of what you all have to deal with every day maintaining this huge project that it might come across the wrong way. My apologies. ❤️ The rest of the comment however I absolutely meant, but it may have come across with the wrong tone due to the way you took the "joke". There was no blame, anger or incredulity intended, but simply an explanation of why I feel that this is a bug and should not be considered an appropriate API change. Now, back to the problem at hand:
I'm not using anything other than what Rails provides. I know that, when I was reaching for a way to do a union on two
If you mean that insofar as certain
I'll definitely see about getting a repo up that you can test.
If that's the case, then I think having a Thanks all. |
@tenderlove I did one more quick dig through and it appears that maybe This was transparent to me before because it was coincidental that the Personally I think it would be desirable for Just let me know what you all decide to do (if anything) and I'll be happy submit a PR to make it so. |
It's worth noting that the |
@sgrif sweet yeah, I think what we've come to in this issue is whether @tenderlove, @matthewd and/or @rafaelfranca have come to a decision on whether or not:
|
|
@sgrif I know it's not ready to be a public API, I was mentioning that I think it should be. And that I'd be willing to do the work. So you're saying that you don't think that If so, that's fine, I just want to make sure we're on the same page. |
@jfelchner we might eventually grow some If you're unioning two relations that are Quite Different Indeed, though, that seems beyond the realm of what Relation can support: if you have a Relation, we're fairly obliged to be sure it corresponds to rows of the matching AR::Base class's table. (That doesn't quite hold when Given that you're returning raw SQL, maybe talking to Arel would in fact be more in line with your goal? Insert disclaimer about Arel's comparatively unstable API here... as you've just encountered 😉. Perhaps there's room for us to make the AR::Relation -> Arel transition smoother, wrt bind params? There is an actionable point here, though I wouldn't consider it a direct offshoot of this issue: active_record/relation/delegation.rb#L94-L96 should be 🔥; if there's anything that should legitimately delegate, it should be explicit. |
I don't know if this belongs in Arel or in ActiveRecord so I'll move it if necessary.
As of Rails 4.2,
to_sql
's behavior has changed. Previously when I had anActiveRelation
and I calledto_sql
on it, I would get a SQL statement that I could copy and paste directly into Postgres' console or use in afind_by_sql
call.Currently in Rails 4.2 I get back a SQL statement that is identical except that it parameterizes it by removing all of the variable bits.
Here's a real life example (with the names stripped and aligned for your viewing pleasure):
Effectively here's the code that's running:
As a minor version release shouldn't break backward compatibility I see this as a fairly large problem.
The text was updated successfully, but these errors were encountered: