Skip to content
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

#307 provide a way to build values for IN clause #309

Closed
wants to merge 1 commit into from

Conversation

doom369
Copy link
Contributor

@doom369 doom369 commented Feb 23, 2019

Currently clickhouse jdbc driver doesn't provide any way to specify dynamic number of values for IN clause. For example,

List<Integer> list = Arrays.asList(1,2,3,4,5);
statement.setObject(1, list);

for where id in (?) will always build an array:

WHERE id IN ([1,2,3,4,5])

while result should be:

WHERE id IN (1,2,3,4,5)

Fixes #307.

This PR breaks back compatibility for those who uses setObject method with list. They need to use array instead of the list in order to preserve previous behaviour.

@Au6ojlut
Copy link

Well, there is one way to do so. You can convert list of objects for in clause to string like 1,2,3,4,5, then convert it to byte[] and setObject(index, byte[]).

Yeah, it looks awful but it works...

@doom369
Copy link
Contributor Author

doom369 commented Aug 20, 2019

Yes, there are workarounds, however current clickhouse flow is not the same as in other drivers like postgres, so merging this PR will bring the same (and expected) flow as in other drivers. So migration from other solutions would be even simpler. The only problem - back compatibility. I think for major version this could be merged.

@den-crane
Copy link
Collaborator

note: For huge lists (>100.000) external data can be used https://clickhouse.yandex/docs/en/operations/table_engines/external_data/

@alex-krash
Copy link
Contributor

Binding multiple values for IN() section is a common problem for any JDBC driver.
We are not going to merge this PR, moreover it brakes backward compatibility.

@doom369
Copy link
Contributor Author

doom369 commented Aug 28, 2019

@alex-krash no problem.

For those who are interested in this and some other fixes/improvements we are gonna release own fork soon of this jdbc driver here https://github.com/blynkkk/clickhouse4j.

We already removed guava, jackson dependencies and working on making pluggable http client in order to make driver almost dependency free.

@doom369 doom369 closed this Aug 28, 2019
@himgang
Copy link

himgang commented Feb 4, 2020

Well, there is one way to do so. You can convert list of objects for in clause to string like 1,2,3,4,5, then convert it to byte[] and setObject(index, byte[]).

Yeah, it looks awful but it works...

query = "select * from table where platform IN (?) limit 10;"

StringBuilder sb = new StringBuilder();
sb.append("1").append(",").append("2");
statement.setObject(3, sb.toString().getBytes());
@Au6ojlut
I am unable to get this to work for IN clause.
getting exception :
Caused by: java.lang.Throwable: Code: 62, e.displayText() = DB::Exception: Syntax error: failed at position 189: \x28\x31\x2C\x32\x29 group by url, domain ,groupedSections limit 1 FORMAT TabSeparatedWithNamesAndTypes;. Unrecognized token (version 19.17.6.36 (official build))

Please Suggest alternative or correct format, If I am making a mistake.

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.

Is there any way to provide IN clause?
5 participants