Skip to content

Error when attempting to use PostgreSQL JSON operators #1614

Closed
@danielbobbert

Description

@danielbobbert

When I try to use a PostreSQL JSON operator containing a question mark, org.hibernate.reactive.pool.impl.PostgresParameters will turn the question mark into a $n parameter filler, which breaks the query. Escaping the question mark doesn't help either, since the escaped question mark is then passed to PostgreSQL verbatim, which is also invalid.

So I either get
error executing SQL statement [ERROR: syntax error at or near "\" (42601)] [select e1_0.id from test.Entity e1_0 where ((jsonb_extract_path(e1_0.child_entity,'flags') $1| array[$2])=true] caused by java.sql.SQLException: ERROR: syntax error at or near "$"
because the question mark is replaced, or
error executing SQL statement [ERROR: syntax error at or near "\" (42601)] [select e1_0.id from test.Entity e1_0 where ((jsonb_extract_path(e1_0.child_entity,'flags') \?| array[$1])=true] caused by java.sql.SQLException: ERROR: syntax error at or near "\"
because the escaped question mark is left unchanged (but including the escape sequence), while the correct final SQL would look like this:
select e1_0.id from test.Entity e1_0 where ((jsonb_extract_path(e1_0.child_entity,'flags') ?| array[$1])=true
(question mark unaltered and unescaped).

PostgresParameters$Parser should be improved such that

  • it either doesn't replace question marks if they are immediately followed by | or &, such that operators ?| and ?& can be used directly, or
  • it offers a way to escape question marks in a way that this escape sequence is turned into a single question mark in the final SQL, e.g. recognize ?? and turn that into ?

The second option would even be preferable, because a single question mark can also be a valid operator, as in jsonb ? text → boolean.

See https://www.postgresql.org/docs/current/functions-json.html for details on JSON operators.

If changing PostgresParameters is not an option, it would be helpful if the selection of the Parameter substitution could be overridden by the application, so that I could plugin my own handler. But currently Parameters.instance(Dialect) is all static, so even though the selection is dialect-specific, there is no way to provide a custom Parameters implementation (through a hook in the Dialect or some other kind of configuration).

In previous versions of Hibernate Reactive, I could work around this by overwriting Dialect.addSqlHintOrComment() because that was being called after parameter substitution, so I could "fix" the SQL and do my own (un)escaping of JSON operators, but with the latest version of Hibernate Reactive, this is no longer possible, because parameter substitution is called last.

Metadata

Metadata

Assignees

Labels

bugSomething isn't working

Type

No type

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions