Query History
The Query Engine maintains a complete execution history for every query processed. This history supports audit compliance, performance analysis, debugging, and user-facing query review.
Endpoint
GET /v1/queries/my-historyRequired Headers
| Header | Type | Description |
|---|---|---|
X-Tenant-ID | UUID | The tenant identifier |
X-User-ID | UUID | The user whose history to retrieve |
Authorization | String | Bearer JWT token |
Query Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
status | String | No | Filter by execution status (COMPLETED, FAILED, etc.) |
page | int | No | Page number (0-based, default: 0) |
size | int | No | Page size (default: 20) |
sort | String | No | Sort field and direction (e.g., submittedAt,desc) |
Implementation
The QueryController delegates to the QueryHistoryService:
@GetMapping("/my-history")
public ResponseEntity<Page<QueryResponse>> getUserHistory(
@RequestHeader("X-Tenant-ID") UUID tenantId,
@RequestHeader("X-User-ID") UUID userId,
@RequestParam(required = false) String status,
Pageable pageable) {
Page<QueryResponse> history = historyService.getQueryHistory(tenantId, userId, status, pageable);
return ResponseEntity.ok(history);
}curl Example
# Get recent query history for the current user
curl -s "http://query-engine:8080/v1/queries/my-history?page=0&size=10&sort=submittedAt,desc" \
-H "X-Tenant-ID: 550e8400-e29b-41d4-a716-446655440000" \
-H "X-User-ID: 6ba7b810-9dad-11d1-80b4-00c04fd430c8" \
-H "Authorization: Bearer $JWT_TOKEN"Response
{
"content": [
{
"executionId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"status": "COMPLETED",
"engineType": "TRINO",
"rowCount": 42,
"bytesScanned": 1048576,
"executionTimeMs": 1250,
"cacheHit": false,
"submittedAt": "2026-02-12T09:45:00Z",
"completedAt": "2026-02-12T09:45:01.250Z"
},
{
"executionId": "b2c3d4e5-f6a7-8901-bcde-f12345678901",
"status": "FAILED",
"engineType": "CLICKHOUSE",
"executionTimeMs": 350,
"cacheHit": false,
"errorMessage": "Table 'analytics.nonexistent' does not exist",
"submittedAt": "2026-02-12T09:30:00Z",
"completedAt": "2026-02-12T09:30:00.350Z"
}
],
"totalElements": 156,
"totalPages": 16,
"size": 10,
"number": 0,
"first": true,
"last": false
}Filtering by Status
# Get only failed queries
curl -s "http://query-engine:8080/v1/queries/my-history?status=FAILED&page=0&size=20" \
-H "X-Tenant-ID: 550e8400-e29b-41d4-a716-446655440000" \
-H "X-User-ID: 6ba7b810-9dad-11d1-80b4-00c04fd430c8" \
-H "Authorization: Bearer $JWT_TOKEN"Valid status values: PENDING, QUEUED, RUNNING, COMPLETED, FAILED, CANCELLED, TIMEOUT.
Result Retrieval from History
Once you have an executionId from the history, you can retrieve the full results:
# Retrieve results for a specific execution
curl -s "http://query-engine:8080/v1/queries/a1b2c3d4-e5f6-7890-abcd-ef1234567890/results?page=0&size=1000" \
-H "X-Tenant-ID: 550e8400-e29b-41d4-a716-446655440000" \
-H "Authorization: Bearer $JWT_TOKEN"Results are stored in the QueryResultStorageService and remain available for the configured retention period.
Data Retention
Query execution metadata is stored in PostgreSQL. The QueryExecution entity captures:
| Field | Description |
|---|---|
id | Unique execution identifier |
tenantId | Tenant isolation key |
userId | User who executed the query |
queryText | The SQL query text |
queryHash | SHA-256 hash for deduplication |
engineType | Which engine executed the query |
status | Final execution status |
rowCount | Number of rows returned |
bytesScanned | Data volume processed |
executionTimeMs | Total execution time |
cacheHit | Whether the result was served from cache |
errorMessage | Error details for failed queries |
submittedAt | Submission timestamp |
completedAt | Completion timestamp |