-
Notifications
You must be signed in to change notification settings - Fork 2.1k
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
Fix valuesForUndefined actual query being executed. Fixes #1268 #1269
Fix valuesForUndefined actual query being executed. Fixes #1268 #1269
Conversation
30f0fa2
to
2e9781e
Compare
I'll review this. I didn't even knew that other drivers had |
if(this.client && this.client.prepBindings) { | ||
defaults.bindings = this.client.prepBindings(defaults.bindings); | ||
} | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not sure if this is correct place to put prepare bindings... e.g. in that case it will be ran multiple times for queryBuilder.toString()
or queryBuilder.toQuery()
methods (https://github.com/tgriesser/knex/blob/master/src/interface.js#L7).
Looks like there is already code in dialect side, which tries to do it in MSSQL https://github.com/tgriesser/knex/blob/master/src/dialects/mssql/index.js#L103 and oracle https://github.com/tgriesser/knex/blob/master/src/dialects/oracle/index.js#L129
but for some reason postgres doesn't have it in place https://github.com/tgriesser/knex/blob/master/src/dialects/postgres/index.js#L132 it wasn't there either for SQLite and I think that oracles stream version of query didn't call that either...
Probably it would be safest to call it somewhere in common code, like maybe here, but in that case we need to remove calls to it from other places. And all the places where toSQL
is used should be checked that preparing bindings doesn't get called multiple times as a side effect...
It could make sense though that when we get bindings we prepare them right away and then bindings everywhere would be already prepared... only bad thing in that would be that if client is given to e.g. knex.raw
later on, bindings will not be updated correctly for that client.
@wubzz I'm not sure yet, how and where bindings should be prepared... do you have any new ideas how to do this consistent way? I'm not a big fan of putting that call to every dialect either... |
@elhigu 👍 I also dislike keeping such fundamental function calls seperated in each dialect, because that's doomed to fail one day when someone adds a new dialect and forgets to call What do you think about removing all current The case about var qb = knex(tableName);
qb.where({test: 1});
console.log(qb.toString());
qb.orWhere({test: 2});
console.log(qb.toString()); Both |
@wubuzz how does it sound if |
af7be5d
to
5aa2c8a
Compare
@elhigu I like that idea. Pushed changes! |
if(this.client && this.client.prepBindings) { | ||
defaults.bindings = this.client.prepBindings(defaults.bindings); | ||
} | ||
defaults.bindings = this.client.prepBindings(defaults.bindings || []); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is here possible that this.client doesn't exist? e.g. in case require('knex').raw('? ?', [undefined, 'wat']).toSQL();
EDIT: looks like raw has its own toSQL... could there be any other case where this.client
is undefined?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good catch! Didn't think about raw
being exposed on the main knex import.
…oSQL() instead. Enforce 'bindings' to always be present in .toSQL() resultset.
…lso add a test so this does not break in the future.
48b0f6a
to
31bcd10
Compare
31bcd10
to
b32fadf
Compare
@rhys-vdw do you have any idea about that |
No, we could perhaps blame it? Generally I'd say that if a feature is undocumented and untested then it is an implementation detail. But with Knex there seems to be a large amount of "discoverable" functionality. Might @bendrucker or @tgriesser be able to shed any light on this? |
As this PR fixes a pretty crucial bug and is not a breaking change I am going to merge this so that it's included in the next release. Should some information come to light regarding |
good call 👍 |
Original issue #1268 |
This was a doosey and a half.. The main issue was that
prepBindings
was not being called in theQueryCompiler
.Interestingly however, some
prepBindings
that weren't being called also resulted in invalid tests, specifically for postgres. Reason for this is that thepg
module and knex's ownprepBindings
->prepareValue
convertsNumbers
toStrings
prior to executing the query. I'm mentioning this so you know why I had to change a few tests.I also had to do a hacky-fix to one of the tests that involved
undefined
values for sqlite3 to prevent theTypeError
being thrown. Since it does not supportvalueForUndefined
, the entire test crashed after applyingprepBindings
, which was to be expected.cc @rhys-vdw @elhigu @chrisfrancis27