"""The SQL reference for Pydantic Logfire.

This resource was generated by an LLM when trying to summarize the https://logfire.pydantic.dev/docs/reference/sql/ page
with the following prompt:

> I want to include this sql.md as a resource to an MCP server that I'm creating (Logfire MCP). I need you to format
> this document in a way that would remove all human not-needed information and only give me what is useful for the LLM.
"""


async def sql_reference() -> str:
    """Contains a reference for the SQL syntax that can be used to query the Logfire database.

    This tool should be called before any other tool.
    """
    return """
# Logfire SQL Reference

## Database System
Logfire uses Apache DataFusion with PostgreSQL-compatible syntax. Extended with JSON functions and operators like `->>`.

## Tables

### records
Primary table containing spans and logs. Each row represents a span or log (span with no duration). A trace is a collection of spans sharing the same `trace_id`, structured as a tree.

### metrics
Contains pre-aggregated numerical data, more efficient for certain queries than `records`.

### records_full
Complete table including pending spans. `records` is a subset excluding pending spans.

## Core Columns

### span_name
String label shared by similar records (low cardinality). Template without arguments filled in.
- HTTP: method and route (e.g., `'GET /users/{id}'`)
- Database: operation (e.g., `'SELECT'`, `'INSERT'`)
- Logfire SDK: template string (e.g., `'beware: {thing}'`)

### message
Human-readable description with arguments filled in.
- HTTP: method and actual path (e.g., `'GET /users/123'`)
- Database: SQL query summary
- Use `LIKE` operator for queries: `WHERE message LIKE '%pattern%'`

### attributes
JSON object with arbitrary structured data. Query with `->>` operator:
- Single level: `attributes->>'key' = 'value'`
- Nested: `attributes->>'nested'->>'key'`

### tags
Array of strings for grouping records. Query with `array_has(tags, 'tag_name')`.
Set via `_tags` parameter in Logfire SDK or `logfire.tags` attribute in OpenTelemetry.

### level
Severity level stored as integer but supports string comparisons:
- `level = 'warn'` matches warning level
- `level > 'info'` finds notable records
- Common values: `info` (9), `warn` (13), `error` (17)
- Convert: `level_num('warn')` returns 13, `level_name(level)` returns string

## Span Tree Structure

### trace_id
32-character hex string identifying the trace. Include in SELECT for clickable links.

### span_id
16-character hex string identifying individual span within trace. Always combine with `trace_id` in WHERE clauses for efficiency.

### parent_span_id
Identifies parent span in tree structure.
- Root spans: `WHERE parent_span_id IS NULL`
- Join parent/child:
```sql
FROM records parent_records
JOIN records child_records
    ON child_records.trace_id = parent_records.trace_id
    AND child_records.parent_span_id = parent_records.span_id
```

## Timestamps

### start_timestamp
UTC time when span/log was created. Use for time filtering:
`start_timestamp >= now() - interval '5 minutes'`

For dashboards: `time_bucket($resolution, start_timestamp)`

### end_timestamp
UTC time when span completed. Same as `start_timestamp` for logs.

### duration
Duration in seconds. `null` for logs.
Example: `duration > 2` for spans longer than 2 seconds.

## Exception Handling

### is_exception
Boolean indicating exception recorded on span/log.

### exception_type
Fully qualified exception class name (e.g., `ValueError`).

### exception_message
Exception message string. Empty string if no message, `null` if not an exception.

### exception_stacktrace
Full formatted traceback (multiline string).

## Resource Attributes

### otel_resource_attributes
JSON object with OpenTelemetry resource attributes. Query with `->>` operator.

### deployment_environment
Environment name (e.g., `production`, `staging`).
From `otel_resource_attributes->>'deployment.environment.name'` or `deployment.environment`.

### service_name
Service identifier (e.g., `web-api`). Adds colored bubble in UI.
Set via `service_name` in `logfire.configure()` or `LOGFIRE_SERVICE_NAME` env var.

### service_version
Service version (e.g., `1.2.3` or git hash).

### service_instance_id
Unique instance identifier (random UUID by default).

### process_pid
Process ID, updated on fork.

## HTTP-Specific Columns

### http_response_status_code
HTTP status code as integer. Query `>= 400` for errors.
From `attributes->>'http.response.status_code'` or `http.status_code`.

### url_full
Full URL from `attributes->>'url.full'` or `http.url`.

### http_route, http_method, url_path, url_query
Direct mappings from OpenTelemetry semantic conventions.

## Other Columns

### otel_scope_name
OpenTelemetry scope/library name (e.g., `logfire`, `opentelemetry.instrumentation.django`).

### log_body
Body content for OpenTelemetry logs (not spans). Can be string or JSON object.

### kind
Record type: `span`, `log`, `span_event`, `pending_span`.
Note: `records` table excludes `pending_span` records.

## Query Patterns

### Find exceptions that are errors
```sql
WHERE is_exception AND level >= 'error'
```

### Filter by service and timeframe
```sql
WHERE service_name = 'web-api'
AND start_timestamp >= now() - interval '1 hour'
```

### Find HTTP errors
```sql
WHERE http_response_status_code >= 400
```

### Search attributes
```sql
WHERE attributes->>'user_id' = '123'
AND attributes->>'action' LIKE '%delete%'
```

### Parent-child span relationships
```sql
SELECT p.message as parent, c.message as child
FROM records p
JOIN records c ON c.trace_id = p.trace_id
AND c.parent_span_id = p.span_id
```

### Time-series aggregation (for dashboards)
```sql
SELECT
    time_bucket($resolution, start_timestamp) as time,
    count(*) as requests
FROM records
WHERE otel_scope_name LIKE '%fastapi%'
GROUP BY time_bucket($resolution, start_timestamp)
```

## Performance Tips

- Include `service_name` filters when possible
- Use `span_name` over `message` for filtering
- Always combine `span_id` with `trace_id` in WHERE clauses
- Prefer `start_timestamp` over `created_at`
- Use `level > 'info'` for notable events only
"""
