-
Notifications
You must be signed in to change notification settings - Fork 10
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
Fixed internal error in pinot queries caused due to question mark (?) in query parameter. #73
Changes from 4 commits
d09dd1b
31eba2c
5fff160
8aa904c
d161575
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -81,13 +81,19 @@ private PinotClient(String pathType, String path) { | |
} | ||
|
||
public ResultSetGroup executeQuery(String statement, Params params) { | ||
/* | ||
PreparedStatement preparedStatement = buildPreparedStatement(statement, params); | ||
return preparedStatement.execute(); | ||
*/ | ||
return connection.execute(new Request(SQL_FORMAT, resolveStatement(statement, params))); | ||
} | ||
|
||
public Future<ResultSetGroup> executeQueryAsync(String statement, Params params) { | ||
/* | ||
PreparedStatement preparedStatement = buildPreparedStatement(statement, params); | ||
return preparedStatement.executeAsync(); | ||
*/ | ||
return connection.executeAsync(new Request(SQL_FORMAT, resolveStatement(statement, params))); | ||
} | ||
|
||
private PreparedStatement buildPreparedStatement(String statement, Params params) { | ||
|
@@ -102,5 +108,47 @@ private PreparedStatement buildPreparedStatement(String statement, Params params | |
.forEach((i, b) -> preparedStatement.setString(i, Hex.encodeHexString(b.toByteArray()))); | ||
return preparedStatement; | ||
} | ||
|
||
@VisibleForTesting | ||
/* | ||
* Pinot PreparedStatement creates invalid query if one of the parameters has '?' in its value. | ||
* Sample pinot query : select * from table where team in (?, ?, ?).. Now say parameters are: | ||
* 'abc', 'pqr with (?)' and 'xyz'.. | ||
* | ||
* Now, on executing PreparedStatement:fillStatementWithParameters method on this will return | ||
* select * from table where team in ('abc', 'pqr with ('xyz')', ?) -- which is clearly wrong | ||
* (what we wanted was select * from table where team in ('abc', 'pqr with (?)', 'xyz')).. | ||
* | ||
* The reason is the usage of replaceFirst iteration in the pinot PreparedStatement method.. | ||
* | ||
* Hence written this custom method to resolve the query statement rather than relying on Pinot's | ||
* library method. | ||
* This is a temporary fix and can be reverted when the Pinot issue gets resolved | ||
* Raised an issue in incubator-pinot github repo: apache/incubator-pinot#6834 | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Interesting find! |
||
*/ | ||
String resolveStatement(String query, Params params) { | ||
singhalprerana marked this conversation as resolved.
Show resolved
Hide resolved
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. What happens in this method when the number of There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. if number of params are more, we drop the extras and if it's less, we replace |
||
String[] queryParts = query.split("\\?"); | ||
singhalprerana marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
String[] parameters = new String[queryParts.length]; | ||
params.getStringParams().forEach((i, p) -> parameters[i] = getStringParam(p)); | ||
params.getIntegerParams().forEach((i, p) -> parameters[i] = String.valueOf(p)); | ||
params.getLongParams().forEach((i, p) -> parameters[i] = String.valueOf(p)); | ||
params.getDoubleParams().forEach((i, p) -> parameters[i] = String.valueOf(p)); | ||
params.getFloatParams().forEach((i, p) -> parameters[i] = String.valueOf(p)); | ||
params | ||
.getByteStringParams() | ||
.forEach((i, p) -> parameters[i] = getStringParam(Hex.encodeHexString(p.toByteArray()))); | ||
|
||
StringBuilder sb = new StringBuilder(); | ||
for (int i = 0; i < queryParts.length; i++) { | ||
sb.append(queryParts[i]); | ||
sb.append(parameters[i] != null ? parameters[i] : ""); | ||
} | ||
return sb.toString(); | ||
} | ||
|
||
private String getStringParam(String value) { | ||
singhalprerana marked this conversation as resolved.
Show resolved
Hide resolved
|
||
return "'" + value.replace("'", "''") + "'"; | ||
} | ||
} | ||
} |
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.
nice documentation 💯