Conflict with Postgresql jsonb operators #519
Comments
The problem is that the postgres dialect replaces every question mark with $ for the parameters bindings before executing the query in The easiest fix is probably changing the regex to only replace occurrences of a question mark at the end or any followed by space, comma with $. @tgriesser any thoughts? |
That seemed to be what I was thinking as well, though I'm not sure if the issue is complicated by the changes to raw which splits on |
|
So a single question mark is also a valid operator. Maybe escaping/replacing the question mark if no param was supplied and converting it back right before execution is a solution. |
@vschoettke take a look at the PR I just opened and see if that's what you were thinking. It basically does what you described, allow for raw queries to have a ? operator so long as there are no bindings in the same raw query. Replaces them temporarily with $Q and then replaces them in the positionBindings. |
@tgriesser your PR looks good to me. If somebody wants to use bindings and a question mark as is then |
One way of fixing this completely (and keep things future-proof for other dialects) would be to generate the SQL text as an array instead of a flat string, starting a new array element at the position of each binding. For example, instead of: { method: 'select',
options: undefined,
bindings: [ 3857, 999999 ],
sql: 'select "geom", ? as "srid" from "map" where ("id" = ?)' } ...we'd have: { method: 'select',
options: undefined,
bindings: [ 3857, 999999 ],
sql: ['select "geom", ', ' as "srid" from "map" where ("id" = ', ')'] } This means that each dialect would get the appropriate placeholders by just calling |
Any updates on this issue? |
+1 Is there any workarounds how I could make queries with json ?,?|,?& operators already with latest stable knex version? |
I'm also curious whether this will be fixed soon. I'll need this before I can switch my generic web-based query tool over to using knex, since this would prevent the user from being able to use the JSONB operators. @tgriesser Your PR looks fine for now, since it would provide a workaround for the time being. Eventually, I think it might make more sense to switch to something like I suggested above, but for now I think it'd be useful to at least get some fix merged. |
Hi @whitelynx. I believe @tgriesser is currently away but I'm happy to get a fix merged. If someone who knows the code base is able to review and update the PR as necessary, I'm happy to facilitate by merging it into master. |
@tgriesser +1, I use JSONB all over the place :) |
This is also a problem with hstore methods.
|
This is also a problem when using Code:
SQL:
|
@zacronos said:
I believe the correct way to do that with the current version of knex is to provide it as a parameter (then it is automatically escaped correctly, as well as avoiding this issue): console.log(knex.table('blah').insert({col1: knex.raw('?', [' http://www.google.com/?q=foobar']), col2: {a:1}}).toString()); |
@whitelynx, ah, that does seem to work. Thanks! |
This has been a big issue for us. Have recently started to use jsonb columns. Any update on the PR? |
@eknkc There is an existing PR. Not sure what the hold up is. |
Actually looks like it's passing, but I don't know the code base well enough to review it. |
@rhys-vdw, the PR passes tests, but it has merge conflicts. I took a look myself earlier to see what it would take, and unfortunately the code involved has changed quite a bit since the PR was created. I believe at least one of the modified files no longer even exists. It's possible it would be easier for someone to create a new PR from scratch rather than try to merge the existing one, but I don't know the codebase, so I can't say for sure. |
The JDBC driver seems to have solved this using knex.raw("SELECT * FROM items WHERE tags ?? ?", ["tagname"]) for SELECT * FROM items WHERE tags ? 'tagname' |
I would expect a more general purpose escaping scheme like |
+1 for |
Except, looks like
https://github.com/tgriesser/knex/blob/master/test/tape/raw.js#L12 |
Good catch, @elhigu. Perhaps |
Looks like we need to do |
I know it's been a couple of months but I am still in this predicament on 0.9 can anyone let me know what is going on with this query? qb.whereRaw("tags \\?& array['" + Array(tags.length + 1).join("?").split("").join("','") + "']", tags) the error i get is select "id" from "tablename" where tags \$1 array['foo','bar'] and "locale" = $2 order by "created_at" desc limit $3 offset $4 - syntax error at or near "\" It seems the escape sequence doesn't get applied in any case. I would appreciate it if anyone can give light to this. |
I'm getting same kind of results... looks like e.g. when one calls knex.from('test_table_two').whereRaw("(json_data->'me')::jsonb \\?& array['keyOne', 'keyTwo']").where('id', '>', 1).toString() select * from "test_table_two" where (json_data->\'me\')::jsonb \\\'1\'& array[\'keyOne\', \'keyTwo\'] and "id" > ? Normal case when one just executes query it goes a bit different route to I'll write test for this case so that |
@jamoy I added pull request to fix your issue |
thank you very much @elhigu wish I knew the codebase enough to contribute. hoping this would get merged soon |
@SeanCannon, in my codebase I saw this working just fine over a year ago after it was fixed. Chances are very good that if you're seeing a similar issue, it is a new problem, not a continuation of this problem. I suggest you create a new Issue, complete with the version of knex you're using, example code that demonstrates the problem, and output of the error and/or expected vs actual results. |
|
Be sure you have jsonb field but not json !! |
Hi!
I have sql:
If i run this sql direct in postgresql client it work fine
If i run this sql through node-postgres it work fine again:
If i run raw sql by knex, it fail with error (below listed):
This Error
I think that it fail because of i used jsonb operator '?&', precise only one symbol '?'
Reference to PostgreSQL JSONB operators
The text was updated successfully, but these errors were encountered: