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
[CALCITE-2955] SQL queries after first query in same statement have no results returned #1132
Conversation
…o results returned
Is it possible to add a test case for this? |
Also check CI failure |
…o results returned
@hsyuan hi, the travis shows the error in RexProgramFuzzyTest#checkUnknownAs, but it seems this PR does not change the file. The Travis log link is Travis-ci-log, any suggestions? |
reopen the pr to trigger CI |
@@ -608,6 +608,8 @@ public MetaResultSet getTableTypes(ConnectionHandle ch) { | |||
new ArrayList<List<Object>>()); | |||
boolean done = fetchMaxRowCount == 0 || rows.size() < fetchMaxRowCount; | |||
@SuppressWarnings("unchecked") List<Object> rows1 = (List<Object>) rows; | |||
// Set ResultSet to null for supporting multi queries in same statement. | |||
stmt.setResultSet(null); |
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.
This is too aggressive :(
The iterator is not released after a call ended because it might not be fully read. If I'm not wrong, setting it to null would cause infinite loop when result row count is large enough.
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.
Thanks for your review and sorry for lately reply @zhztheplayer , updated the PR to address your comment.
Thanks for the changes @leesf. And could you please add a unit test to guard against large result set? Now that the fetch size in Avatica is defaulted to 100[1]. You can make the rows of return larger than the number. |
@@ -608,6 +608,10 @@ public MetaResultSet getTableTypes(ConnectionHandle ch) { | |||
new ArrayList<List<Object>>()); | |||
boolean done = fetchMaxRowCount == 0 || rows.size() < fetchMaxRowCount; | |||
@SuppressWarnings("unchecked") List<Object> rows1 = (List<Object>) rows; | |||
if (done) { |
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.
The logic looks still vulnerable. If the first iterator is not "done", then we execute second query the result will be wrong. I think the correct fix should relate to the CLOSE phase of ResultSet instances in client side, but I tested against calling resultSet.close()
before executing the second query and nothing happened. Maybe something was wrong there.
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.
@zhztheplayer Thanks for you quick look again. And i don't know what you means
calling resultSet.close() before executing the second query and nothing happened
Since I think there is no need to call ResultSet#close.
And I add an unit test for fetching more than 100 result. Please take a look. Thanks.
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.
It seems that stmt.setResultSet(null)
should be called by the operation of closing the ResultSet object on client side (we can treat the re-executing of Statement object implicitly closes the current ResultSet opened by it), because inside the method CalciteMetaImpl#fetch
we can barely know exactly when we should execute a new query (please correct me if I am wrong).
For example, you can check following test case:
@Test public void testFoo() throws Exception {
try (Connection remoteConnection = getRemoteConnection()) {
final Statement statement = remoteConnection.createStatement();
StringBuffer stringBuffer = new StringBuffer();
stringBuffer.append("values ");
final int resultSize = 1000;
for (int i = 0; i < resultSize; i++) {
stringBuffer.append("(").append(i).append(", ").append(i + 1).append(")");
if (i != resultSize - 1) {
stringBuffer.append(", ");
}
}
final String sql = stringBuffer.toString();
ResultSet resultSet = statement.executeQuery(sql);
resultSet = statement.executeQuery("values (1, 'a')");
int n = 0;
while (resultSet.next()) {
++n;
}
assertThat(n, equalTo(1));
}
}
80f411d
to
ca27fe9
Compare
49cb002
to
8768a23
Compare
see jira:CALCITE-2955