Skip to content

add ?-contained operator support#187

Closed
tminglei wants to merge 4 commits intopgjdbc:masterfrom
tminglei:master
Closed

add ?-contained operator support#187
tminglei wants to merge 4 commits intopgjdbc:masterfrom
tminglei:master

Conversation

@tminglei
Copy link
Contributor

Currently it seems PgJDBC didn't support ?-contained operator escaping, which lead to some ?-contained operators, such as hstore's ?&/?| and ltree's ?/?~/?@ and so on, can't be used in PreparedStatement.

This pull request try to resolve the problem.

How to use it?
double mark the ? when passing a raw sql to connection's prepareStatement method, as below:

st = conn.prepareStatement("SELECT 'Top.Collections.Pictures.Astronomy.Stars'::ltree ?? '{\"*.Astronomy.*\"}'::lquery[];");

and PgJDBC won't recognize the ?? as a parameter placeholder, and restore it back to ? before sending to postgres server.

Pls help review and give your concerns or suggestions. Thanks!

@tminglei
Copy link
Contributor Author

Any feedback?

@davecramer
Copy link
Member

I'm not crazy about duplicating the ? here, but what alternatives do we have?

@tminglei
Copy link
Contributor Author

@davecramer that's also what I want to know.
Any way we can use to support operations like ?&/?|/?/?~/?@ ?

@polobo
Copy link

polobo commented Oct 25, 2014

The better but more invasive option is to have a libpq compatibility mode
and require $n for parameters and free up the question mark for the
operator.

I don't believe it is possible to smartly interpret/parse a question mark
and determine if it is an operator or a parameter.

I'd prefer "?" to "??" And explain it to mean that the question mark is
escaped past the first layer (JDBC-parameter) and passed onto the next
layer (PostgreSQL parser) as-is to be interpreted accordingly (likely as an
operator). Is this possible?

David J.

On Saturday, October 25, 2014, Dave Cramer notifications@github.com wrote:

I'm not crazy about duplicating the ? here, but what alternatives do we
have?


Reply to this email directly or view it on GitHub
#187 (comment).

@kjurka
Copy link
Member

kjurka commented Oct 25, 2014

What about some variant of the existing JDBC escape syntax? "col {xxx ?} ?" where xxx is some keyword to indicate that the result should be copied into the resulting sql literally.

@polobo
Copy link

polobo commented Oct 25, 2014

I can imagine someone wanting to turn off jdbc escape processing but still
wanting to be able to utilize this specific capability. Especially since
someone using jdbc escape processing sequences likely would not be using
custom operators since they are trying to write portable code.

Besides, using the standard syntax for a non-standard feature could be
confusing.

I'd consider making it so that you have to turn jdbc escape processing off
in order for this to work...

David J.

On Saturday, October 25, 2014, Kris Jurka notifications@github.com wrote:

What about some variant of the existing JDBC escape syntax? "col = {xxx ?}
?" where xxx is some keyword to indicate that the result should be copied
into the resulting sql literally.


Reply to this email directly or view it on GitHub
#187 (comment).

@tminglei
Copy link
Contributor Author

@kjurka the escape way isn't work, because it will be unescaped back before preparing statement.
@polobo in fact, I don't care about '??' or '?', both of them should be ok to me.

@davecramer
Copy link
Member

After some thinking ?? is probably the simplest. Anything else seems worse.

Dave Cramer

On 25 October 2014 22:19, 涂名雷 notifications@github.com wrote:

@kjurka https://github.com/kjurka the escape way isn't work, because it
will be unescaped back before preparing statement.
@polobo https://github.com/polobo in fact, I don't care about '??' or
'?', both of them should be ok to me.


Reply to this email directly or view it on GitHub
#187 (comment).

@ringerc
Copy link
Member

ringerc commented Oct 28, 2014

?? is the only sane way to go IMO, since we can't do the ideal thing and roll back time then make ? reserved in PostgreSQL. That ship has sailed.

\? isn't too bad, but I think we're better off sticking to the SQL convention of doubling things to escape them like 'this is a single quote: '''

It could have a BC impact if someone was using the v2 protocol and set two parameters, so that ?? became 'param1''param2', which then gets interpreted as:

param1'param2

... but really, that's a don't do that kind of situation.

I don't think it'll have any other BC impact, and it's pretty simple and easy to understand.

@polobo
Copy link

polobo commented Oct 29, 2014

Edit: I see the logic in sql-esque escaping by doubling; Craig's comment did not come through completely in e-mail so I missed the reasoning.

Dave & Craig:

Care to elaborate on why ? would be worse than ??

?

David J.

On Sun, Oct 26, 2014 at 2:05 AM, Dave Cramer notifications@github.com
wrote:

After some thinking ?? is probably the simplest. Anything else seems
worse.

Dave Cramer

On 25 October 2014 22:19, 涂名雷 notifications@github.com wrote:

@kjurka https://github.com/kjurka the escape way isn't work, because
it
will be unescaped back before preparing statement.
@polobo https://github.com/polobo in fact, I don't care about '??' or
'?', both of them should be ok to me.

@ringerc
Copy link
Member

ringerc commented Oct 29, 2014

On 10/29/2014 08:02 AM, David Johnston wrote:

Care to elaborate on why ? would be worse than ??

My main reason for that preference is that ?? is more consistent with
"identifers with embedded "" quotes" and 'literals with embedded ''
quotes' .

I don't think it's significantly different from a BC PoV; writing ? in
current PgJDBC makes little sense.

Craig Ringer http://www.2ndQuadrant.com/
PostgreSQL Development, 24x7 Support, Training & Services

@kjurka
Copy link
Member

kjurka commented Oct 29, 2014

The reason I like the escape clause as opposed to these other suggestions is that you can write the same code for both prepared and non-prepared usage. I think it is awkward to have to use different syntax for identical queries executed by different methods.

@tminglei yes, the escape processing currently wouldn't work because it does the full replace processing before looking for parameters, but that is not required. You could do escape processing which returned an object which had knowledge of the escaped constructs so that parameter detection would skip over them.

@kjurka
Copy link
Member

kjurka commented Oct 29, 2014

No, wait. I see people are suggesting to do this escaping for all ?? even in plain (unprepared) sql. That might be OK, but the danger @ringerc notes isn't just ?? for two parameters, but an operator named ?? for unprepared code, right?

@polobo
Copy link

polobo commented Oct 29, 2014

@kjurka - didn't even consider non-prepared...and yes escaping there would be problematic since the ?? sequence can be a valid within an operator. "?" exhibits the same problem :(

Are there currently any PostgreSQL features (thinking dollar quoting though it may no longer be a problem) that doesn't play well with JDBC escaping such that people would want to use this feature without having to allow all JDBC escape sequences?

I do think having non-parameterized queries able to be executed by either statement or preparedstatement is something that is a worse case option.

@ringerc
Copy link
Member

ringerc commented Oct 29, 2014

On 10/29/2014 08:18 AM, Kris Jurka wrote:

The reason I like the escape clause as opposed to these other
suggestions is that you can write the same code for both prepared and
non-prepared usage. I think it is awkward to have to use different
syntax for identical queries executed by different methods.

Oh, good point.

That tips it in favour of the JDBC escape syntax for me, despite how
horribly verbose and ugly it is.

Rather than using an escape for ? I'd want to have a more general way to
say "this text is literal and should not be processed for JDBC escapes,
parameters, etc".

Craig Ringer http://www.2ndQuadrant.com/
PostgreSQL Development, 24x7 Support, Training & Services

@davecramer
Copy link
Member

Dave Cramer

On 28 October 2014 20:42, Craig Ringer notifications@github.com wrote:

On 10/29/2014 08:18 AM, Kris Jurka wrote:

The reason I like the escape clause as opposed to these other
suggestions is that you can write the same code for both prepared and
non-prepared usage. I think it is awkward to have to use different
syntax for identical queries executed by different methods.

Oh, good point.

That tips it in favour of the JDBC escape syntax for me, despite how
horribly verbose and ugly it is.

Rather than using an escape for ? I'd want to have a more general way to
say "this text is literal and should not be processed for JDBC escapes,
parameters, etc".

+1 for a "literal escape"

Craig Ringer http://www.2ndQuadrant.com/
PostgreSQL Development, 24x7 Support, Training & Services


Reply to this email directly or view it on GitHub
#187 (comment).

@ringerc
Copy link
Member

ringerc commented Dec 1, 2014

If you rebase this on top of git head and squash away the reverted commit, I'll merge the updated pull request.

You're working on top of a local branch named master as well, so it's harder for me to offer good instructions on how to do that.

Assuming your local working branch is called master I'd start by renaming it.

  • git checkout master
  • git branch -m contains-operator

Then fetch pgjdbc master:

  • git remote add pgjdbc https://github.com/pgjdbc/pgjdbc.git
  • git fetch pgjdbc
  • git checkout pgjdbc/master
  • git checkout -b pgjdbc-master

and rebase on top of it:

  • git checkout contains-operator
  • git tag before-rebase
  • git rebase pgjdbc-master

then squash away your unintended changes with an interactive rebase:

  • git rebase -i pgjdbc-master

and after testing, push the reworked branch, retaining the upstream branch name master so the PR gets updated:

  • git push --force --set-upstream origin contains-operator:master

In case of issues, you can abort any open rebase and reset to the before rebase state:

  • git rebase --abort
  • git reset --hard before-rebase

@tminglei
Copy link
Contributor Author

tminglei commented Dec 1, 2014

Hi @ringerc can I create a new branch on local, based on pgjdbc/pgjdbc, then redo the changes, then send a new PR again? It seems easier to me.

@ringerc
Copy link
Member

ringerc commented Dec 1, 2014

Sure, if that's easier for you, no problem.

Sorry for the hassle, it's just that a lot has changed recently. I'd probably just merge anyway, but I don't want the noise of the deleted commit in the final history.

@tminglei
Copy link
Contributor Author

tminglei commented Dec 1, 2014

Hi @ringerc You're welcome! In fact, I also enjoy a clean commit history. :)

Resent the PR changes in #227. Can you help review again?

@tminglei tminglei closed this Dec 1, 2014
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.

5 participants