MATIH Platform is in active MVP development. Documentation reflects current implementation status.
9. Query Engine & SQL
Query Execution
Query Cancellation

Query Cancellation

The Query Engine supports cancelling both running and queued queries. Cancellation is important for controlling resource consumption, aborting expensive queries, and providing users with the ability to stop long-running operations.


Endpoint

POST /v1/queries/{executionId}/cancel

Required Headers

HeaderTypeDescription
X-Tenant-IDUUIDThe tenant identifier
AuthorizationStringBearer JWT token

Cancellation Flow

The QueryController delegates to the QueryExecutionService.cancelQuery() method:

@PostMapping("/{executionId}/cancel")
public ResponseEntity<Map<String, Object>> cancelQuery(
        @RequestHeader("X-Tenant-ID") UUID tenantId,
        @PathVariable UUID executionId) {
 
    boolean cancelled = executionService.cancelQuery(tenantId, executionId);
    return ResponseEntity.ok(Map.of(
            "executionId", executionId,
            "cancelled", cancelled,
            "message", cancelled ? "Query cancelled" : "Query could not be cancelled"
    ));
}

The cancellation implementation uses a database-level update to atomically transition queries in PENDING, QUEUED, or RUNNING states to CANCELLED:

@Transactional
public boolean cancelQuery(UUID tenantId, UUID executionId) {
    int updated = executionRepository.cancelQuery(executionId);
    if (updated > 0) {
        log.info("Query cancelled: {}", executionId);
        meterRegistry.counter("query.cancelled", "tenant", tenantId.toString()).increment();
        return true;
    }
    return false;
}

curl Example

# Cancel a running query
curl -X POST http://query-engine:8080/v1/queries/d290f1ee-6c54-4b01-90e6-d701748f0851/cancel \
  -H "X-Tenant-ID: 550e8400-e29b-41d4-a716-446655440000" \
  -H "Authorization: Bearer $JWT_TOKEN"

Success Response

{
  "executionId": "d290f1ee-6c54-4b01-90e6-d701748f0851",
  "cancelled": true,
  "message": "Query cancelled"
}

Failure Response (Query Already Completed)

{
  "executionId": "d290f1ee-6c54-4b01-90e6-d701748f0851",
  "cancelled": false,
  "message": "Query could not be cancelled"
}

Cancellation via Workload Manager

For queries managed through the workload system, cancellation also releases resource reservations:

// WorkloadController
@PostMapping("/cancel/{queryId}")
public ResponseEntity<Map<String, Object>> cancelQuery(
        @PathVariable String queryId,
        @RequestParam(required = false) String reservationId) {
    boolean cancelled = workloadManager.cancelQuery(queryId, reservationId);
    return ResponseEntity.ok(Map.of(
            "queryId", queryId,
            "cancelled", cancelled
    ));
}

The WorkloadManager.cancelQuery() method removes the query from the queue (if queued) and releases any resource reservations (if executing):

public boolean cancelQuery(String queryId, String reservationId) {
    boolean removed = queryQueue.remove(queryId);
    if (reservationId != null) {
        resourcePool.release(reservationId);
    }
    if (removed) {
        meterRegistry.counter("query.workload.cancelled").increment();
    }
    return removed || reservationId != null;
}

States That Can Be Cancelled

Current StateCancellableEffect
PENDINGYesRecord updated to CANCELLED
QUEUEDYesRemoved from queue, record updated
RUNNINGYesEngine-level cancellation attempted, record updated
COMPLETEDNoReturns cancelled: false
FAILEDNoReturns cancelled: false
CANCELLEDNoAlready cancelled, returns cancelled: false
TIMEOUTNoAlready terminated, returns cancelled: false

Engine-Level Cancellation

For Trino queries, cancellation triggers a JDBC statement cancellation that propagates to the Trino coordinator, which then cancels all running tasks across workers. The TrinoQueryStrategy detects cancellation via a SQLException containing the word "cancelled":

} catch (SQLException e) {
    if (e.getMessage() != null && e.getMessage().contains("cancelled")) {
        throw new QueryCancelledException("Query was cancelled");
    }
    throw new QueryExecutionException("Trino query failed: " + e.getMessage(), e);
}

Metrics

MetricTypeDescription
query.cancelledCounterTotal queries cancelled, tagged by tenant
query.workload.cancelledCounterQueries cancelled via workload manager