Skip to content
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

Stop button for queries doesn't work in SQL Lab #29475

Open
3 tasks done
DianaLyM opened this issue Jul 3, 2024 · 1 comment
Open
3 tasks done

Stop button for queries doesn't work in SQL Lab #29475

DianaLyM opened this issue Jul 3, 2024 · 1 comment
Labels
data:connect:kyuubi sqllab Namespace | Anything related to the SQL Lab

Comments

@DianaLyM
Copy link

DianaLyM commented Jul 3, 2024

Bug description

Connected to Apache Kyuubi, stop request returned: {“message”:“Could not cancel query”}

How to reproduce the bug

When I click stop in SQL Lab, nothing happens.

Screenshots/recordings

image

Superset version

4.0.1

Python version

3.9

Node version

16

Browser

Chrome

Additional context

No response

Checklist

  • I have searched Superset docs and Slack and didn't find a solution to my problem.
  • I have searched the GitHub issue tracker and didn't find a similar bug report.
  • I have checked Superset's logs for errors and if I found a relevant Python stacktrace, I included it here as text in the "additional context" section.
@dosubot dosubot bot added data:connect:kyuubi sqllab Namespace | Anything related to the SQL Lab labels Jul 3, 2024
Copy link

dosubot bot commented Jul 3, 2024

Hi @DianaLyM! I'm here to help you with bugs, questions, and becoming a contributor. Let's work on this together while we wait for a human maintainer.

To resolve the issue where the stop button for queries in SQL Lab does not work and results in the error message {"message":"Could not cancel query"} when connected to Apache Kyuubi, you need to ensure that the cancel_query function is properly implemented for the Kyuubi engine in the db_engine_spec.

The cancel_query function attempts to cancel a running query by using a cancel query ID stored in the query's extra JSON. If the cancel query ID is not set or the database engine does not support explicit query cancellation, the function will return False.

Here is a relevant snippet from the cancel_query function:

def cancel_query(query: Query) -> bool:
    """
    Cancel a running query.

    Note some engines implicitly handle the cancelation of a query and thus no explicit
    action is required.

    :param query: Query to cancel
    :return: True if query cancelled successfully, False otherwise
    """

    if query.database.db_engine_spec.has_implicit_cancel():
        return True

    # Some databases may need to make preparations for query cancellation
    query.database.db_engine_spec.prepare_cancel_query(query)

    if query.extra.get(QUERY_EARLY_CANCEL_KEY):
        # Query has been cancelled prior to being able to set the cancel key.
        # This can happen if the query cancellation key can only be acquired after the
        # query has been executed
        return True

    cancel_query_id = query.extra.get(QUERY_CANCEL_KEY)
    if cancel_query_id is None:
        return False

    with query.database.get_sqla_engine(
        catalog=query.catalog,
        schema=query.schema,
        source=QuerySource.SQL_LAB,
    ) as engine:
        with closing(engine.raw_connection()) as conn:
            with closing(conn.cursor()) as cursor:
                return query.database.db_engine_spec.cancel_query(
                    cursor, query, cancel_query_id
                )

Additionally, ensure that the stop_query method in the QueryDAO class is correctly implemented. The stop_query method should handle the query status and call the cancel_query function appropriately. Here is the relevant part of the stop_query method:

@staticmethod
def stop_query(client_id: str) -> None:
    query = db.session.query(Query).filter_by(client_id=client_id).one_or_none()
    if not query:
        raise QueryNotFoundException(f"Query with client_id {client_id} not found")
    if query.status in [
        QueryStatus.FAILED,
        QueryStatus.SUCCESS,
        QueryStatus.TIMED_OUT,
    ]:
        logger.warning(
            "Query with client_id could not be stopped: query already complete",
        )
        return

    if not sql_lab.cancel_query(query):
        raise SupersetCancelQueryException("Could not cancel query")

    query.status = QueryStatus.STOPPED
    query.end_time = now_as_float()

To fix the issue, ensure that the db_engine_spec for Apache Kyuubi correctly implements the cancel_query method and handles the cancel_query_id appropriately. If the Kyuubi engine does not support explicit query cancellation, you may need to implement a workaround or ensure that the cancel_query_id is correctly set and used.

Additionally, in the frontend code, ensure that the postStopQuery function in superset-frontend/src/SqlLab/actions/sqlLab.js is correctly implemented to handle the stopping of queries. Here is the relevant part of the postStopQuery function:

export function postStopQuery(query) {
  return function (dispatch) {
    return SupersetClient.post({
      endpoint: '/api/v1/query/stop',
      body: JSON.stringify({ client_id: query.id }),
      headers: { 'Content-Type': 'application/json' },
    })
      .then(() => dispatch(stopQuery(query)))
      .then(() => dispatch(addSuccessToast(t('Query was stopped.'))))
      .catch(() =>
        dispatch(addDangerToast(t('Failed at stopping query. %s', query.id))),
      );
  };
}

Ensure that the stopQuery action is dispatched correctly and that the backend endpoint /api/v1/query/stop is properly handling the stop request [1][2][3].

To continue talking to Dosu, mention @dosu.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
data:connect:kyuubi sqllab Namespace | Anything related to the SQL Lab
Projects
None yet
Development

No branches or pull requests

1 participant