Skip to content

Datanode: validate that a query id belongs to the calling session - #18643

Open
ColinLeeo wants to merge 1 commit into
apache:masterfrom
ColinLeeo:colin/query-id-session-ownership
Open

ColinLeeo wants to merge 1 commit into
apache:masterfrom
ColinLeeo:colin/query-id-session-ownership

Conversation

@ColinLeeo

Copy link
Copy Markdown
Collaborator

Summary

fetchResultsV2, fetchResults and closeOperation take a queryId from the client and resolve it in the coordinator wide map of running queries. The request was only checked for login, not for whether that queryId was issued to the calling session, so a request could stream the result of a query, advance its cursor, or release it, on behalf of another session.

This PR adds a session level validation of the client supplied queryId. When the query is not owned by the calling session, the request returns NO_PERMISSION and the running query is left untouched. A queryId that is no longer running keeps the previous behaviour, so a closeOperation sent after a result set was fully consumed still succeeds as usual.

Changes

  • IClientSession#containsQueryId(Long statementId, long queryId) added. ClientSession and InternalClientSession implement it over the statementId -> queryId bookkeeping the sessions already keep; MqttClientSession and RestClientSession cannot submit queries and return false. A null statement id scans all of the session's query ids, which is what V1 fetchResults sends (the JDBC data set does not set a statement id on fetch).
  • ClientRPCServiceImpl: the check is applied in fetchResultsV2, fetchResults and closeOperation. The check runs after the existing lookup, so an unknown or killed queryId still returns QUERY_WAS_KILLED as before, and a rejected fetch neither records operation latency nor cleans the query up.
  • closeOperation only rejects when the query is still running; releasing an already released queryId remains a no-op.
  • Added the en/zh message and QueryOwnershipTest, covering the session bookkeeping, both fetch APIs, and the close path.

Verification

  • mvn test-compile -DskipTests and mvn test-compile -DskipTests -P with-zh-locale
  • mvn -pl iotdb-core/datanode -am -Dtest=QueryOwnershipTest -DfailIfNoTests=false test -- 6 tests, all pass
  • mvn spotless:apply -pl iotdb-core/datanode

fetchResultsV2, fetchResults and closeOperation resolve the queryId sent by
the client in the coordinator wide map of running queries, without checking
which session submitted that query. Add a per session validation of the
queryId and return NO_PERMISSION when it was not issued to the calling
session, so that the running query is neither read nor released by another
session.

- add IClientSession.containsQueryId, implemented on ClientSession and
  InternalClientSession over the statementId -> queryId bookkeeping that
  already exists, and on MqttClientSession/RestClientSession which cannot
  submit queries
- check the queryId in fetchResultsV2, fetchResults and closeOperation; a
  queryId that is no longer running keeps the previous behaviour
- a rejected fetch does not record latency or clean up the query
- add the en/zh message and a unit test covering the two fetch APIs, the
  close path and the session level bookkeeping
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.

1 participant