This is an automated email from the ASF dual-hosted git repository.
michaelsmith pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/impala.git
The following commit(s) were added to refs/heads/master by this push:
new 54642b254 IMPALA-12878: Report invalid query if finalized
54642b254 is described below
commit 54642b2549c38625c868f09815b61170e568cdb9
Author: Michael Smith <[email protected]>
AuthorDate: Wed Mar 6 14:00:18 2024 -0800
IMPALA-12878: Report invalid query if finalized
Fixes a case introduced by IMPALA-12493 where a query is closed again in
the middle of unregistering - which appears to be possible with
cancel_query_and_validate_state - returns "Query not yet running"
instead of "Invalid or unknown query handle".
IMPALA-12493 moved checks for whether a query is inflight before an
atomic CompareAndSwap to mark a QueryDriver as finalized. As part of
that change, a query that was Finalized and removed from
inflight_queries - but not yet removed from query_driver_map_ - could
report "Query not yet running". Updates the check for that error to also
verify the query has not been finalized; if it has, we let the next
conditional handle that case and return "Invalid or unknown query
handle".
Also ensures cancelled queries are closed in test_web_pages tests so
assertions that num_in_flight_queries == 0 at the start of tests are
valid when running the whole suite serially. This doesn't come up in
automated tests because the cases that care about that assertion are
marked execute_serially, while the cases that failed to close a query
were not.
Testing: adds a test to test_cancellation that ensures we get the
expected "Invalid or unknown query handle" when close() is delayed in
calling QueryDriver::Finalize.
Change-Id: I3bf910f499147a09352f9dcb755037b0d8616dfd
Reviewed-on: http://gerrit.cloudera.org:8080/21110
Reviewed-by: Impala Public Jenkins <[email protected]>
Tested-by: Impala Public Jenkins <[email protected]>
---
be/src/runtime/query-driver.cc | 5 ++++-
be/src/service/impala-server.cc | 4 ++++
tests/query_test/test_cancellation.py | 28 ++++++++++++++++++++++++++++
tests/webserver/test_web_pages.py | 1 +
4 files changed, 37 insertions(+), 1 deletion(-)
diff --git a/be/src/runtime/query-driver.cc b/be/src/runtime/query-driver.cc
index 15e3c0e19..edd18c49d 100644
--- a/be/src/runtime/query-driver.cc
+++ b/be/src/runtime/query-driver.cc
@@ -494,7 +494,10 @@ void QueryDriver::HandleRetryFailure(Status* status,
string* error_msg,
Status QueryDriver::Finalize(
QueryHandle* query_handle, bool check_inflight, const Status* cause) {
- if (check_inflight && !(*query_handle)->is_inflight()) {
+ // If the query's not inflight yet, return an appropriate error. If the query
+ // has been finalized and removed from inflight_queries (but not yet removed
+ // from query_driver_map_) we want to fall-through to the next check.
+ if (check_inflight && !(*query_handle)->is_inflight() && !finalized_.Load())
{
return Status("Query not yet running");
}
diff --git a/be/src/service/impala-server.cc b/be/src/service/impala-server.cc
index ef3c29f36..3a307e1de 100644
--- a/be/src/service/impala-server.cc
+++ b/be/src/service/impala-server.cc
@@ -1533,6 +1533,10 @@ Status ImpalaServer::UnregisterQuery(const TUniqueId&
query_id, bool check_infli
QueryHandle query_handle;
RETURN_IF_ERROR(GetActiveQueryHandle(query_id, &query_handle));
+ if (check_inflight) {
+ DebugActionNoFail(query_handle->query_options(),
"FINALIZE_INFLIGHT_QUERY");
+ }
+
// Do the work of unregistration that needs to be done synchronously. Once
// Finalize() returns, the query is considered unregistered from the
client's point of
// view. If Finalize() returns OK, this thread is responsible for doing the
diff --git a/tests/query_test/test_cancellation.py
b/tests/query_test/test_cancellation.py
index e4b718b47..21fc59497 100644
--- a/tests/query_test/test_cancellation.py
+++ b/tests/query_test/test_cancellation.py
@@ -25,6 +25,7 @@ import threading
from time import sleep
from RuntimeProfile.ttypes import TRuntimeProfileFormat
from tests.beeswax.impala_beeswax import ImpalaBeeswaxException
+from tests.common.test_dimensions import add_mandatory_exec_option
from tests.common.test_vector import ImpalaTestDimension
from tests.common.impala_test_suite import ImpalaTestSuite
from tests.util.cancel_util import cancel_query_and_validate_state
@@ -275,3 +276,30 @@ class TestCancellationFullSort(TestCancellation):
def test_cancel_sort(self, vector):
self.execute_cancel_test(vector)
+
+
+class TestCancellationFinalizeDelayed(ImpalaTestSuite):
+ @classmethod
+ def get_workload(self):
+ return 'tpch'
+
+ @classmethod
+ def add_test_dimensions(cls):
+ super(TestCancellationFinalizeDelayed, cls).add_test_dimensions()
+
+ # Test with a small delay in QueryDriver::Finalize from close() to check
that queries
+ # that are finalized as a result of closing the session correctly return
"Invalid or
+ # unknown query handle" to the close() RPC.
+ add_mandatory_exec_option(cls, 'debug_action',
'FINALIZE_INFLIGHT_QUERY:SLEEP@10')
+
+ # Debug action is independent of file format, so only testing for
+ # table_format=parquet/none in order to avoid a test dimension explosion.
+ cls.ImpalaTestMatrix.add_constraint(lambda v:
+ v.get_value('table_format').file_format == 'parquet'
+ and v.get_value('table_format').compression_codec == 'none')
+
+ def test_cancellation(self, vector):
+ query = "select l_returnflag from tpch_parquet.lineitem"
+ cancel_delay = 0
+ cancel_query_and_validate_state(self.client, query,
+ vector.get_value('exec_option'), vector.get_value('table_format'),
cancel_delay)
diff --git a/tests/webserver/test_web_pages.py
b/tests/webserver/test_web_pages.py
index 9757b0d72..61e8990c9 100644
--- a/tests/webserver/test_web_pages.py
+++ b/tests/webserver/test_web_pages.py
@@ -537,6 +537,7 @@ class TestWebPage(ImpalaTestSuite):
response_json = json.loads(responses[0].text)
finally:
self.client.cancel(query_handle)
+ self.client.close_query(query_handle)
return response_json
@pytest.mark.xfail(run=False, reason="IMPALA-8059")