Fix trino-cli to display plans for EXPLAIN ANALYZE for update statements#13907
Conversation
There was a problem hiding this comment.
Can the server not set the update type in results if it's an explain query?
There was a problem hiding this comment.
I tried this, see my comment below with link to a pr that has links to 2 others :D I did 3 different approaches but none of them seems good enough
electrum
left a comment
There was a problem hiding this comment.
I think this is a bug on the server side. We shouldn't set update type if there is a real result.
The client discards results for an update because the server sends a fake result in that case, for compatibility with older clients (many years ago). The client should not be guessing as to the type of result based on the name/shape of the results.
|
Actually, I think we still want to send update type and count, since an We can remove the code that produces the fake result in the server. We should verify that all of our clients support this properly. For the JDBC driver, it needs to properly implement |
@electrum Currently we don't send updateCount, it is set to null for EXPLAIN ANALYZE, we only send updateType. |
|
The reason we have the "discard results" hack in the CLI and JDBC driver is due to the server adding a fake result set for update statements. If we remove that on the server side, then there doesn't need to be any special handling in the clients. With this change, the JDBC driver will need to support the multiple result sets: the update count and the explain analyze output. JDBC explicitly supports multiple results as explained in the Javadoc. We should have the update count be returned first (the first result set) since that will work correctly with older servers that return the fake result set. |
e0beb8d to
4e3e483
Compare
There was a problem hiding this comment.
I think this should still be called but after the call to both renderUpdate and renderResults, on line 168. If results are not consumed, queries can get stuck in the FINISHING phase. Also, there are no other calls to discardResults.
There was a problem hiding this comment.
hmm ok, I will give it a look thanks
There was a problem hiding this comment.
@nineinchnick after renderResults completes, we shouldn't need to do discardResults, should we?
4e3e483 to
89a2ad2
Compare
c09b74c to
666663b
Compare
d5cc678 to
4be06bd
Compare
There was a problem hiding this comment.
I am not sure this is a good change.
It looks we're going to call client.advance(); until we drain the results.
I don't know what are the assumptions for the code above (it originates a while back from 8ccea3a and doesn't carry much comments), but it feels wrong to me.
I think the intention here is
- call
client.advance()until we know the columns of the result, since this information is one of the first send back by the server
if the server now doesn't return columns in some cases, maybe it needs to indicate no columns will ever be provided, so that clients don't need to drain / buffer all the results?
eg some related code in the python client
https://github.com/trinodb/trino-python-client/blob/cffd2b232d9298321c34430f0ac829f6b6ebea8f/trino/client.py#L652-L655
cc. @electrum
There was a problem hiding this comment.
if the server now doesn't return columns in some cases, maybe it needs to indicate no columns will ever be provided, so that clients don't need to drain / buffer all the results?
It always returns the columns, eventually, unless the query fails before it gets analyzed. But it may not happen in the first (or first few) requests, depending on how long the query gets queued, etc.
There was a problem hiding this comment.
But it may not happen in the first (or first few) requests
that's true
It always returns the columns, eventually
@martint Do we always need to produce columns, also for INSERT, CALL, SET or GRANT statements?
There was a problem hiding this comment.
Currently, for update queries this results in updated count being printed twice
trino:tpch> UPDATE nation SET nationkey = 4;
UPDATE: 25 rows
rows
------
25
(1 row)
4be06bd to
cf245ef
Compare
|
@electrum Could you please take a look now? |
There was a problem hiding this comment.
Why go here only when updateCount is null?
There was a problem hiding this comment.
for example -- after this change -- for CTAS we print number of rows written:
trino:default> CREATE TABLE t AS TABLE tpch.tiny.nation;
CREATE TABLE: 25 rows
but for EXPLAIN ANALYZE CTAS we print only the operation name "CREATE TABLE", without the row count:
trino:default> EXPLAIN ANALYZE CREATE TABLE t AS TABLE tpch.tiny.nation;
CREATE TABLE
<query plan>
The query plan is correctly printed, but row count should be too
There was a problem hiding this comment.
I will add a code comment, mainly to avoid printing same information twice as in your comment above #13907 (comment)
There was a problem hiding this comment.
@nineinchnick after renderResults completes, we shouldn't need to do discardResults, should we?
plugin/trino-blackhole/src/test/java/io/trino/plugin/blackhole/TestBlackHoleSmoke.java
Outdated
Show resolved
Hide resolved
plugin/trino-blackhole/src/test/java/io/trino/plugin/blackhole/TestBlackHoleSmoke.java
Outdated
Show resolved
Hide resolved
plugin/trino-blackhole/src/test/java/io/trino/plugin/blackhole/TestBlackHoleSmoke.java
Outdated
Show resolved
Hide resolved
plugin/trino-iceberg/src/test/java/io/trino/plugin/iceberg/BaseIcebergConnectorTest.java
Outdated
Show resolved
Hide resolved
There was a problem hiding this comment.
| assertThat(lines).contains("CREATE TABLE", "Query Plan"); | |
| assertThat(lines).contains("CREATE TABLE: 10 rows", "Query Plan"); |
There was a problem hiding this comment.
It is hard to do it now due to #14253, but that could be a good enhancement for the future
There was a problem hiding this comment.
| assertThat(lines).contains("INSERT", "Query Plan"); | |
| assertThat(lines).contains("INSERT: 1 row", "Query Plan"); |
There was a problem hiding this comment.
It is hard to do it now due to #14253, but that could be a good enhancement for the future
testing/trino-testing/src/main/java/io/trino/testing/AbstractTestEngineOnlyQueries.java
Outdated
Show resolved
Hide resolved
testing/trino-testing/src/main/java/io/trino/testing/TestingTrinoClient.java
Outdated
Show resolved
Hide resolved
testing/trino-testing/src/main/java/io/trino/testing/TestingTrinoClient.java
Outdated
Show resolved
Hide resolved
testing/trino-tests/src/test/java/io/trino/execution/TestGrantOnTable.java
Outdated
Show resolved
Hide resolved
|
Pushing a version without all of the changes to make sure changes so far are correct |
cf245ef to
49769c7
Compare
49769c7 to
931f750
Compare
|
will merge tomorrow |
| if (!resultsConsumed && queryInfo.getOutputStage().isEmpty()) { | ||
| return queryResultRowsBuilder(session) | ||
| .withSingleBooleanValue(createColumn("result", BooleanType.BOOLEAN, supportsParametricDateTime), true) | ||
| .withColumnsAndTypes(ImmutableList.of(), ImmutableList.of()) |
There was a problem hiding this comment.
Just to make sure, could this affect older versions of Trino CLI or other clients?
There was a problem hiding this comment.
If the changes in the Trino CLI don't require these, should they be in separate commits? If they do, would the Trino CLI still work correctly with older Trino servers?
There was a problem hiding this comment.
we run tests against older versions and they work so I think we are fine
There was a problem hiding this comment.
It does seems to affect other clients though probably - see trinodb/trino-python-client#212 (comment)
There was a problem hiding this comment.
Also, PR title could be probably better worded (and release notes as well) to mention we no longer return result sets for queries which don't return output (which is correct behaviour but older code could be relying on this).
There was a problem hiding this comment.
No problem. The comment was meant more to the reviewers. Thanks for the offer - if you want to and feel comfortable with that sure but don't feel responsible for it.
There was a problem hiding this comment.
I feel responsible but not comfortable, what should I do in such a case ?
There was a problem hiding this comment.
@hashhar you know i strive to make PR titles as informative as I can be, but it's also not possible to fit the whole story in that line
the biggest miss is that we broke the Python client, unknowingly.
Would it make sense to have some Python client comaptibility smoke tests within this repo?
This would supplement the ones maintained in the Python client repo. That ones cover current Py client ws current and old servers.
Those new ones would cover current server against older clients.
There was a problem hiding this comment.
I feel responsible but not comfortable, what should I do in such a case ?
No problem. I'd request a review to make sure you can verify the functional changes there match what we did for the JDBC client here. @homar
the biggest miss is that we broke the Python client, unknowingly.
@findepi The Python client isn't my biggest concern - my main concern is this is a user-facing change where if someone wrote code relying on DDL queries as well returning results then they'd be affected (even though it'd be wrong to rely on that in the first place).
We can consider adding a smoke test here that tests current server against current client only so that at least we can ensure that there's at-least 1 working Python (and Go) client for each Trino server release.
I'll create a separate issue about such tests and let's continue here.
|
What was actually fixed with this PR? The current version (397) shows query plans for explain analyze: |
|
|
for posterity, i've updated #14245 (comment) too |
Description
Previously trino-cli didn't display plans for EXPLAIN ANALYZe
Related issues, pull requests, and links
Documentation
(x) No documentation is needed.
( ) Sufficient documentation is included in this PR.
( ) Documentation PR is available with #prnumber.
( ) Documentation issue #issuenumber is filed, and can be handled later.
Release notes
( ) No release notes entries required.
(x) Release notes entries required with the following suggested text: