From d278d98cbb664e02f064e7a703d5233c8e5d5ee8 Mon Sep 17 00:00:00 2001 From: Flo Date: Fri, 7 Nov 2025 16:21:56 +0100 Subject: [PATCH 1/3] feat: update ch parser and add WITH FILL docs --- apps/docs/analytics/getting-started.mdx | 7 + apps/docs/analytics/overview.mdx | 28 ++- apps/docs/analytics/query-examples.mdx | 222 ++++++++++++++++++ apps/docs/analytics/quick-reference.mdx | 29 +++ apps/docs/analytics/schema-reference.mdx | 47 ++-- .../bad_request/invalid_analytics_query.mdx | 23 +- go/Makefile | 2 +- go/apps/api/openapi/openapi-generated.yaml | 1 - .../v2/analytics/getVerifications/index.yaml | 2 - go/go.mod | 2 +- go/go.sum | 2 + 11 files changed, 317 insertions(+), 48 deletions(-) diff --git a/apps/docs/analytics/getting-started.mdx b/apps/docs/analytics/getting-started.mdx index 1ea887bceb..18922a3f80 100644 --- a/apps/docs/analytics/getting-started.mdx +++ b/apps/docs/analytics/getting-started.mdx @@ -151,6 +151,13 @@ Each object in the `data` array contains fields from your SELECT clause. The fie You can filter queries to specific APIs or users. Use `key_space_id` to filter by API (find this identifier in your API settings) and `external_id` to filter by user. These fields support standard SQL operators: `=`, `!=`, `IN`, `NOT IN`, `<`, `>`, etc. + + **Automatic filtering:** All queries are automatically filtered based on your root key's permissions: + + - **Workspace filtering:** All queries are scoped to your workspace. You **do not need** to filter by `workspace_id`. + - **API filtering:** If your root key has `api..read_analytics` permissions (scoped to a specific API), queries are automatically filtered to that API's `key_space_id`. If your root key has `api.*.read_analytics` (all APIs), you should filter by `key_space_id` yourself to query specific APIs. + + Queries are subject to resource limits (execution time, memory, result size, and quota). See [Query Restrictions](/analytics/query-restrictions) for diff --git a/apps/docs/analytics/overview.mdx b/apps/docs/analytics/overview.mdx index a7653f80fa..f81fa1591c 100644 --- a/apps/docs/analytics/overview.mdx +++ b/apps/docs/analytics/overview.mdx @@ -19,6 +19,10 @@ Unkey Analytics provides a powerful SQL interface to query your API key verifica - **Generate reports** on API usage patterns, top users, and performance metrics - **Monitor and alert** on verification outcomes, rate limits, and errors + + **Automatic filtering:** All queries are scoped to your workspace automatically. If your root key is scoped to a specific API (`api..read_analytics`), queries are also filtered to that API's `key_space_id`. + + ## How it Works Every key verification request is automatically stored and aggregated across multiple time-series tables: @@ -43,18 +47,18 @@ You can query these tables using standard SQL to: Every verification event contains: -| Field | Type | Description | -| --------------- | ------------- | ----------------------------------------------------------------------------------------------------------------------------------------- | -| `request_id` | String | Unique identifier for each request | -| `time` | Int64 | Unix millisecond timestamp | -| `workspace_id` | String | Your workspace identifier (automatically filtered) | -| `key_space_id` | String | Your KeySpace identifier (e.g., `ks_1234`). Find this in your API settings. | -| `external_id` | String | Your user's identifier (e.g., `user_abc`) | -| `key_id` | String | Individual key identifier | -| `outcome` | String | Verification result: `VALID`, `RATE_LIMITED`, `INVALID`, `EXPIRED`, `DISABLED`, `INSUFFICIENT_PERMISSIONS`, `FORBIDDEN`, `USAGE_EXCEEDED` | -| `region` | String | Unkey region that handled the verification | -| `tags` | Array(String) | Custom tags added during verification | -| `spent_credits` | Int64 | Number of credits spent on this verification (0 if no credits were spent) | +| Field | Type | Description | +| --------------- | ------------- | ------------------------------------------------------------------------------------------------------------------------------------------ | +| `request_id` | String | Unique identifier for each request | +| `time` | Int64 | Unix millisecond timestamp | +| `workspace_id` | String | Your workspace identifier (**automatically filtered** - you don't need to filter by this) | +| `key_space_id` | String | Your KeySpace identifier (e.g., `ks_1234`). **Automatically filtered** if your root key is scoped to a single API. | +| `external_id` | String | Your user's identifier (e.g., `user_abc`) | +| `key_id` | String | Individual key identifier | +| `outcome` | String | Verification result: `VALID`, `RATE_LIMITED`, `INVALID`, `EXPIRED`, `DISABLED`, `INSUFFICIENT_PERMISSIONS`, `FORBIDDEN`, `USAGE_EXCEEDED` | +| `region` | String | Unkey region that handled the verification | +| `tags` | Array(String) | Custom tags added during verification | +| `spent_credits` | Int64 | Number of credits spent on this verification (0 if no credits were spent) | ## Use Cases diff --git a/apps/docs/analytics/query-examples.mdx b/apps/docs/analytics/query-examples.mdx index 51811d5935..fc97262ba3 100644 --- a/apps/docs/analytics/query-examples.mdx +++ b/apps/docs/analytics/query-examples.mdx @@ -86,6 +86,76 @@ curl -X POST https://api.unkey.com/v2/analytics.getVerifications \ +### All outcomes in a single row + +Get all verification outcomes in one row with individual columns for each outcome type. + + +```sql SQL +SELECT + sumIf(count, outcome = 'VALID') AS valid, + sumIf(count, outcome = 'RATE_LIMITED') AS rateLimited, + sumIf(count, outcome = 'INVALID') AS invalid, + sumIf(count, outcome = 'NOT_FOUND') AS notFound, + sumIf(count, outcome = 'FORBIDDEN') AS forbidden, + sumIf(count, outcome = 'USAGE_EXCEEDED') AS usageExceeded, + sumIf(count, outcome = 'UNAUTHORIZED') AS unauthorized, + sumIf(count, outcome = 'DISABLED') AS disabled, + sumIf(count, outcome = 'INSUFFICIENT_PERMISSIONS') AS insufficientPermissions, + sumIf(count, outcome = 'EXPIRED') AS expired, + SUM(count) AS total +FROM key_verifications_per_day_v1 +WHERE time >= now() - INTERVAL 30 DAY +``` + +```bash cURL +curl -X POST https://api.unkey.com/v2/analytics.getVerifications \ + -H "Authorization: Bearer " \ + -H "Content-Type: application/json" \ + -d '{ + "query": "SELECT sumIf(count, outcome = '\''VALID'\'') AS valid, sumIf(count, outcome = '\''RATE_LIMITED'\'') AS rateLimited, sumIf(count, outcome = '\''INVALID'\'') AS invalid, sumIf(count, outcome = '\''NOT_FOUND'\'') AS notFound, sumIf(count, outcome = '\''FORBIDDEN'\'') AS forbidden, sumIf(count, outcome = '\''USAGE_EXCEEDED'\'') AS usageExceeded, sumIf(count, outcome = '\''UNAUTHORIZED'\'') AS unauthorized, sumIf(count, outcome = '\''DISABLED'\'') AS disabled, sumIf(count, outcome = '\''INSUFFICIENT_PERMISSIONS'\'') AS insufficientPermissions, sumIf(count, outcome = '\''EXPIRED'\'') AS expired, SUM(count) AS total FROM key_verifications_per_day_v1 WHERE time >= now() - INTERVAL 30 DAY" + }' +``` + + + +### All outcomes per key + +Get outcome breakdown for each API key in a single row per key. + + +```sql SQL +SELECT + key_id, + sumIf(count, outcome = 'VALID') AS valid, + sumIf(count, outcome = 'RATE_LIMITED') AS rateLimited, + sumIf(count, outcome = 'INVALID') AS invalid, + sumIf(count, outcome = 'NOT_FOUND') AS notFound, + sumIf(count, outcome = 'FORBIDDEN') AS forbidden, + sumIf(count, outcome = 'USAGE_EXCEEDED') AS usageExceeded, + sumIf(count, outcome = 'UNAUTHORIZED') AS unauthorized, + sumIf(count, outcome = 'DISABLED') AS disabled, + sumIf(count, outcome = 'INSUFFICIENT_PERMISSIONS') AS insufficientPermissions, + sumIf(count, outcome = 'EXPIRED') AS expired, + SUM(count) AS total +FROM key_verifications_per_day_v1 +WHERE time >= now() - INTERVAL 30 DAY +GROUP BY key_id +ORDER BY total DESC +LIMIT 100 +``` + +```bash cURL +curl -X POST https://api.unkey.com/v2/analytics.getVerifications \ + -H "Authorization: Bearer " \ + -H "Content-Type: application/json" \ + -d '{ + "query": "SELECT key_id, sumIf(count, outcome = '\''VALID'\'') AS valid, sumIf(count, outcome = '\''RATE_LIMITED'\'') AS rateLimited, sumIf(count, outcome = '\''INVALID'\'') AS invalid, sumIf(count, outcome = '\''NOT_FOUND'\'') AS notFound, sumIf(count, outcome = '\''FORBIDDEN'\'') AS forbidden, sumIf(count, outcome = '\''USAGE_EXCEEDED'\'') AS usageExceeded, sumIf(count, outcome = '\''UNAUTHORIZED'\'') AS unauthorized, sumIf(count, outcome = '\''DISABLED'\'') AS disabled, sumIf(count, outcome = '\''INSUFFICIENT_PERMISSIONS'\'') AS insufficientPermissions, sumIf(count, outcome = '\''EXPIRED'\'') AS expired, SUM(count) AS total FROM key_verifications_per_day_v1 WHERE time >= now() - INTERVAL 30 DAY GROUP BY key_id ORDER BY total DESC LIMIT 100" + }' +``` + + + ### Daily verification trend Track daily verification patterns over the last 30 days. @@ -847,6 +917,158 @@ curl -X POST https://api.unkey.com/v2/analytics.getVerifications \ +## Filling Gaps in Time Series (WITH FILL) + +When querying time series data, you may have periods with no activity that result in missing time points. ClickHouse's `WITH FILL` clause ensures all time periods are included in results, filling gaps with zeros. + + + `WITH FILL` is particularly useful for creating charts and visualizations where you need consistent time intervals, even when there's no data for some periods. + + + + `WITH FILL` only works when grouping by the time column alone. To include outcome breakdowns or other dimensions, use `sumIf()` to pivot them into columns (see the last example below). + + + + **Type matching:** The `time` column type varies by table: + - **Hourly/Minute tables**: `DateTime` - use `toStartOfHour(now() - INTERVAL N HOUR)` + - **Daily/Monthly tables**: `Date` - use `toDate(now() - INTERVAL N DAY)` or `toDate(toStartOfMonth(...))` + + WITH FILL expressions must match the column type exactly. + + +### Hourly data with gaps filled + +Get hourly verification counts for the last 7 days, including hours with zero activity. + + +```sql SQL +SELECT + time, + SUM(count) as total +FROM key_verifications_per_hour_v1 +WHERE time >= toStartOfHour(now() - INTERVAL 7 DAY) + AND time <= toStartOfHour(now()) +GROUP BY time +ORDER BY time ASC + WITH FILL + FROM toStartOfHour(now() - INTERVAL 7 DAY) + TO toStartOfHour(now()) + STEP INTERVAL 1 HOUR +``` + +```bash cURL +curl -X POST https://api.unkey.com/v2/analytics.getVerifications \ + -H "Authorization: Bearer " \ + -H "Content-Type: application/json" \ + -d '{ + "query": "SELECT time, SUM(count) as total FROM key_verifications_per_hour_v1 WHERE time >= toStartOfHour(now() - INTERVAL 7 DAY) AND time <= toStartOfHour(now()) GROUP BY time ORDER BY time ASC WITH FILL FROM toStartOfHour(now() - INTERVAL 7 DAY) TO toStartOfHour(now()) STEP INTERVAL 1 HOUR" + }' +``` + + + +### Daily data with gaps filled + +Get daily verification counts for the last 30 days, ensuring all days are present. + + +```sql SQL +SELECT + time, + SUM(count) as total +FROM key_verifications_per_day_v1 +WHERE time >= toDate(now() - INTERVAL 30 DAY) + AND time <= toDate(now()) +GROUP BY time +ORDER BY time ASC + WITH FILL + FROM toDate(now() - INTERVAL 30 DAY) + TO toDate(now()) + STEP INTERVAL 1 DAY +``` + +```bash cURL +curl -X POST https://api.unkey.com/v2/analytics.getVerifications \ + -H "Authorization: Bearer " \ + -H "Content-Type: application/json" \ + -d '{ + "query": "SELECT time, SUM(count) as total FROM key_verifications_per_day_v1 WHERE time >= toDate(now() - INTERVAL 30 DAY) AND time <= toDate(now()) GROUP BY time ORDER BY time ASC WITH FILL FROM toDate(now() - INTERVAL 30 DAY) TO toDate(now()) STEP INTERVAL 1 DAY" + }' +``` + + + +### Monthly data with gaps filled + +Get monthly verification counts for the last 12 months with all months included. + + +```sql SQL +SELECT + time, + SUM(count) as total +FROM key_verifications_per_month_v1 +WHERE time >= toDate(toStartOfMonth(now() - INTERVAL 12 MONTH)) + AND time <= toDate(toStartOfMonth(now())) +GROUP BY time +ORDER BY time ASC + WITH FILL + FROM toDate(toStartOfMonth(now() - INTERVAL 12 MONTH)) + TO toDate(toStartOfMonth(now())) + STEP INTERVAL 1 MONTH +``` + +```bash cURL +curl -X POST https://api.unkey.com/v2/analytics.getVerifications \ + -H "Authorization: Bearer " \ + -H "Content-Type: application/json" \ + -d '{ + "query": "SELECT time, SUM(count) as total FROM key_verifications_per_month_v1 WHERE time >= toDate(toStartOfMonth(now() - INTERVAL 12 MONTH)) AND time <= toDate(toStartOfMonth(now())) GROUP BY time ORDER BY time ASC WITH FILL FROM toDate(toStartOfMonth(now() - INTERVAL 12 MONTH)) TO toDate(toStartOfMonth(now())) STEP INTERVAL 1 MONTH" + }' +``` + + + +### Filling gaps with aggregations + +For more complex queries that aggregate by outcome, use a subquery or pivot approach instead of WITH FILL with multiple GROUP BY columns. + + +```sql SQL +-- Pivot outcomes into columns with all days filled +SELECT + time, + sumIf(count, outcome = 'VALID') as valid, + sumIf(count, outcome = 'RATE_LIMITED') as rate_limited, + sumIf(count, outcome = 'INVALID') as invalid, + SUM(count) as total +FROM key_verifications_per_day_v1 +WHERE time >= toDate(now() - INTERVAL 30 DAY) + AND time <= toDate(now()) +GROUP BY time +ORDER BY time ASC + WITH FILL + FROM toDate(now() - INTERVAL 30 DAY) + TO toDate(now()) + STEP INTERVAL 1 DAY +``` + +```bash cURL +curl -X POST https://api.unkey.com/v2/analytics.getVerifications \ + -H "Authorization: Bearer " \ + -H "Content-Type: application/json" \ + -d '{ + "query": "SELECT time, sumIf(count, outcome = '\''VALID'\'') as valid, sumIf(count, outcome = '\''RATE_LIMITED'\'') as rate_limited, sumIf(count, outcome = '\''INVALID'\'') as invalid, SUM(count) as total FROM key_verifications_per_day_v1 WHERE time >= toDate(now() - INTERVAL 30 DAY) AND time <= toDate(now()) GROUP BY time ORDER BY time ASC WITH FILL FROM toDate(now() - INTERVAL 30 DAY) TO toDate(now()) STEP INTERVAL 1 DAY" + }' +``` + + + + + `WITH FILL` only works when grouping by time alone. For outcome breakdowns, use `sumIf()` to pivot outcomes into separate columns as shown above. + + ## Tips for Efficient Queries 1. **Always filter by time** - Use indexes by including time filters diff --git a/apps/docs/analytics/quick-reference.mdx b/apps/docs/analytics/quick-reference.mdx index 15ec58b991..2886966a0d 100644 --- a/apps/docs/analytics/quick-reference.mdx +++ b/apps/docs/analytics/quick-reference.mdx @@ -131,6 +131,28 @@ GROUP BY endpoint ORDER BY requests DESC ``` +### Filling Gaps in Time Series + +**Use for**: Charts and visualizations that need consistent time intervals + +```sql +-- Daily data with all days included (even zero counts) +SELECT time, SUM(count) as total +FROM key_verifications_per_day_v1 +WHERE time >= toDate(now() - INTERVAL 30 DAY) + AND time <= toDate(now()) +GROUP BY time +ORDER BY time ASC + WITH FILL + FROM toDate(now() - INTERVAL 30 DAY) + TO toDate(now()) + STEP INTERVAL 1 DAY +``` + + + See [Query Examples - WITH FILL](/analytics/query-examples#filling-gaps-in-time-series-with-fill) for hourly, daily, and monthly examples with outcome breakdowns. + + ## Table Selection Guide Choose the right table based on your time range: @@ -152,6 +174,13 @@ Choose the right table based on your time range: ## Common Filters + + **Automatic filtering:** All queries are automatically filtered based on your root key permissions: + + - **Workspace:** All queries are scoped to your workspace (no need to filter `workspace_id`) + - **API:** If your root key is scoped to a specific API (`api..read_analytics`), queries are filtered to that API's `key_space_id`. With `api.*.read_analytics` permissions, filter by `key_space_id` yourself. + + ### Time Ranges ```sql diff --git a/apps/docs/analytics/schema-reference.mdx b/apps/docs/analytics/schema-reference.mdx index 087f98f8cd..ab3b1027b5 100644 --- a/apps/docs/analytics/schema-reference.mdx +++ b/apps/docs/analytics/schema-reference.mdx @@ -16,18 +16,18 @@ The `key_verifications_v1` table contains individual verification events as they ### Columns -| Column | Type | Description | -| --------------- | ------------- | ------------------------------------------------------------------------------------------------------- | -| `request_id` | String | Unique identifier for each verification request | -| `time` | Int64 | Unix timestamp in milliseconds when verification occurred | -| `workspace_id` | String | Workspace identifier (automatically filtered to your workspace) | -| `key_space_id` | String | Your KeySpace identifier (e.g., `ks_1234`) - use this to filter by API. Find this in your API settings. | -| `external_id` | String | Your user's identifier (e.g., `user_abc`) - use this to filter by user | -| `key_id` | String | Individual API key identifier | -| `outcome` | String | Verification result (see [Outcome Values](#outcome-values)) | -| `region` | String | Unkey region that handled the verification | -| `tags` | Array(String) | Custom tags added during verification | -| `spent_credits` | Int64 | Number of credits spent on this verification (0 if no credits were spent) | +| Column | Type | Description | +| --------------- | ------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `request_id` | String | Unique identifier for each verification request | +| `time` | Int64 | Unix timestamp in milliseconds when verification occurred | +| `workspace_id` | String | Workspace identifier (**automatically filtered** - you don't need to filter by this) | +| `key_space_id` | String | Your KeySpace identifier (e.g., `ks_1234`). **Automatically filtered** if your root key is scoped to a single API, otherwise filter this yourself. | +| `external_id` | String | Your user's identifier (e.g., `user_abc`) - use this to filter by user | +| `key_id` | String | Individual API key identifier | +| `outcome` | String | Verification result (see [Outcome Values](#outcome-values)) | +| `region` | String | Unkey region that handled the verification | +| `tags` | Array(String) | Custom tags added during verification | +| `spent_credits` | Int64 | Number of credits spent on this verification (0 if no credits were spent) | ### Outcome Values @@ -52,17 +52,17 @@ Pre-aggregated tables provide better query performance for long time ranges. Eac `key_verifications_per_minute_v1` - Aggregated by minute -| Column | Type | Description | -| --------------- | -------- | --------------------------------------------------------- | -| `time` | DateTime | Timestamp (DateTime for minute/hour, Date for day/month) | -| `workspace_id` | String | Workspace identifier | -| `key_space_id` | String | API identifier | -| `external_id` | String | Your user identifier | -| `key_id` | String | API key identifier | -| `outcome` | String | Verification outcome (VALID, RATE_LIMITED, INVALID, etc.) | -| `tags` | Array | Tags associated with verifications | -| `count` | UInt64 | Total verification count for this aggregation | -| `spent_credits` | UInt64 | Total credits spent | +| Column | Type | Description | +| --------------- | -------- | --------------------------------------------------------------------------------------------------------------------------------------------- | +| `time` | DateTime/Date | **DateTime** for minute/hour tables, **Date** for day/month tables | +| `workspace_id` | String | Workspace identifier (**automatically filtered** - you don't need to filter by this) | +| `key_space_id` | String | API identifier. **Automatically filtered** if your root key is scoped to a single API, otherwise filter this yourself. | +| `external_id` | String | Your user identifier | +| `key_id` | String | API key identifier | +| `outcome` | String | Verification outcome (VALID, RATE_LIMITED, INVALID, etc.) | +| `tags` | Array | Tags associated with verifications | +| `count` | UInt64 | Total verification count for this aggregation | +| `spent_credits` | UInt64 | Total credits spent | ### Per Hour Table @@ -291,6 +291,7 @@ WHERE time >= 1704067200000 -- Jan 1, 2024 00:00:00 UTC 3. **Limit result sets** - Add LIMIT clauses to prevent large results 4. **Filter before grouping** - Use WHERE instead of HAVING when possible 5. **Avoid SELECT \*** - Only select columns you need +6. **No need to filter workspace_id** - This is handled automatically based on your authentication ## Query Limits diff --git a/apps/docs/errors/user/bad_request/invalid_analytics_query.mdx b/apps/docs/errors/user/bad_request/invalid_analytics_query.mdx index cc2255c6e9..dfffd53ec3 100644 --- a/apps/docs/errors/user/bad_request/invalid_analytics_query.mdx +++ b/apps/docs/errors/user/bad_request/invalid_analytics_query.mdx @@ -38,14 +38,14 @@ Common causes include: ```sql Wrong - Missing comma SELECT - api_id + key_space_id COUNT(*) as total FROM key_verifications_v1 ``` ```sql Correct SELECT - api_id, + key_space_id, COUNT(*) as total FROM key_verifications_v1 ``` @@ -57,11 +57,15 @@ FROM key_verifications_v1 ```sql Wrong - Unclosed quote -SELECT * FROM key_verifications_v1 WHERE api_id = 'api_123 +SELECT key_space_id, outcome +FROM key_verifications_v1 +WHERE key_space_id = 'ks_123 ``` ```sql Correct -SELECT * FROM key_verifications_v1 WHERE api_id = 'api_123' +SELECT key_space_id, outcome +FROM key_verifications_v1 +WHERE key_space_id = 'ks_123' ``` @@ -71,11 +75,13 @@ SELECT * FROM key_verifications_v1 WHERE api_id = 'api_123' ```sql Wrong - Typo in SELECT -SELCT * FROM key_verifications_v1 +SELCT time, outcome +FROM key_verifications_v1 ``` ```sql Correct -SELECT * FROM key_verifications_v1 +SELECT time, outcome +FROM key_verifications_v1 ``` @@ -86,7 +92,7 @@ Make sure you're using valid column names from your analytics tables: ```sql -- ✓ Valid columns -SELECT time, api_id, outcome, key_id +SELECT time, key_space_id, outcome, key_id FROM key_verifications_v1 WHERE time >= now() - INTERVAL 7 DAY ``` @@ -96,5 +102,6 @@ WHERE time >= now() - INTERVAL 7 DAY If you're stuck with a syntax error: 1. **Check the error message** - It usually tells you exactly where the problem is -2. **Test incrementally** - Start with a simple `SELECT *` and add complexity step by step +2. **Test incrementally** - Start with a simple query like `SELECT time, outcome FROM table_name LIMIT 10` and add complexity step by step 3. **Use a SQL validator** - Many online tools can help spot syntax errors +4. **Check the schema** - Refer to the [Schema Reference](/analytics/schema-reference) for valid column names diff --git a/go/Makefile b/go/Makefile index 678d426dc0..066ae35bde 100644 --- a/go/Makefile +++ b/go/Makefile @@ -44,7 +44,7 @@ build: setup go build -o unkey . generate: setup - go tool buf generate --template ./buf.gen.connect.yaml --clean --path "./proto/ctrl" --path "./proto/krane" --path "./proto/partition" --path "./proto/vault" + go tool buf generate --template ./buf.gen.connect.yaml --clean --path "./proto/ctrl" --path "./proto/krane" --path "./proto/partition" --path "./proto/vault" --path "./proto/cache" go tool buf generate --template ./buf.gen.restate.yaml --path "./proto/hydra" go generate ./... go fmt ./... diff --git a/go/apps/api/openapi/openapi-generated.yaml b/go/apps/api/openapi/openapi-generated.yaml index 22bf93a6f1..2f9afee000 100644 --- a/go/apps/api/openapi/openapi-generated.yaml +++ b/go/apps/api/openapi/openapi-generated.yaml @@ -3418,7 +3418,6 @@ paths: tags: - analytics x-hidden: true - x-speakeasy-ignore: true x-speakeasy-name-override: getVerifications /v2/apis.createApi: post: diff --git a/go/apps/api/openapi/spec/paths/v2/analytics/getVerifications/index.yaml b/go/apps/api/openapi/spec/paths/v2/analytics/getVerifications/index.yaml index 3e6ce834ba..a47d1e528c 100644 --- a/go/apps/api/openapi/spec/paths/v2/analytics/getVerifications/index.yaml +++ b/go/apps/api/openapi/spec/paths/v2/analytics/getVerifications/index.yaml @@ -6,8 +6,6 @@ post: # Hides from mintlify x-hidden: true x-speakeasy-name-override: getVerifications - # Hides from sdk generation - x-speakeasy-ignore: true operationId: analytics.getVerifications summary: Query key verification data description: | diff --git a/go/go.mod b/go/go.mod index ecf51237cf..0e2420578b 100644 --- a/go/go.mod +++ b/go/go.mod @@ -8,7 +8,7 @@ require ( buf.build/gen/go/depot/api/connectrpc/go v1.19.0-20250915125527-3af9e416de91.1 buf.build/gen/go/depot/api/protocolbuffers/go v1.36.10-20250915125527-3af9e416de91.1 connectrpc.com/connect v1.19.0 - github.com/AfterShip/clickhouse-sql-parser v0.4.15 + github.com/AfterShip/clickhouse-sql-parser v0.4.16 github.com/ClickHouse/clickhouse-go/v2 v2.40.1 github.com/aws/aws-sdk-go-v2 v1.36.6 github.com/aws/aws-sdk-go-v2/config v1.29.18 diff --git a/go/go.sum b/go/go.sum index b04ba53b38..d0a61b8992 100644 --- a/go/go.sum +++ b/go/go.sum @@ -12,6 +12,8 @@ github.com/AdaLogics/go-fuzz-headers v0.0.0-20240806141605-e8a1dd7889d6 h1:He8af github.com/AdaLogics/go-fuzz-headers v0.0.0-20240806141605-e8a1dd7889d6/go.mod h1:8o94RPi1/7XTJvwPpRSzSUedZrtlirdB3r9Z20bi2f8= github.com/AfterShip/clickhouse-sql-parser v0.4.15 h1:OJCabxkbtnWHtjkEUH0BHZQGzDGyRrRIoMdR1ayRvJA= github.com/AfterShip/clickhouse-sql-parser v0.4.15/go.mod h1:W0Z82wJWkJxz2RVun/RMwxue3g7ut47Xxl+SFqdJGus= +github.com/AfterShip/clickhouse-sql-parser v0.4.16 h1:gpl+wXclYUKT0p4+gBq22XeRYWwEoZ9f35vogqMvkLQ= +github.com/AfterShip/clickhouse-sql-parser v0.4.16/go.mod h1:W0Z82wJWkJxz2RVun/RMwxue3g7ut47Xxl+SFqdJGus= github.com/Azure/go-ansiterm v0.0.0-20250102033503-faa5f7b0171c h1:udKWzYgxTojEKWjV8V+WSxDXJ4NFATAsZjh8iIbsQIg= github.com/Azure/go-ansiterm v0.0.0-20250102033503-faa5f7b0171c/go.mod h1:xomTg63KZ2rFqZQzSB4Vz2SUXa1BpHTVz9L5PTmPC4E= github.com/ClickHouse/ch-go v0.68.0 h1:zd2VD8l2aVYnXFRyhTyKCrxvhSz1AaY4wBUXu/f0GiU= From c2433c5737271c4ffee996b1ff0326fb4eaee8b3 Mon Sep 17 00:00:00 2001 From: Flo Date: Fri, 7 Nov 2025 16:26:03 +0100 Subject: [PATCH 2/3] fix: allow sumIf --- go/pkg/clickhouse/query-parser/validation.go | 1 + 1 file changed, 1 insertion(+) diff --git a/go/pkg/clickhouse/query-parser/validation.go b/go/pkg/clickhouse/query-parser/validation.go index f8648c6911..e40b9cb19f 100644 --- a/go/pkg/clickhouse/query-parser/validation.go +++ b/go/pkg/clickhouse/query-parser/validation.go @@ -71,6 +71,7 @@ var allowedFunctions = map[string]bool{ // Conditional functions "if": true, + "sumif": true, "case": true, "coalesce": true, "countif": true, From fa631653b2defdb881e291a57705f25c79a8480b Mon Sep 17 00:00:00 2001 From: Flo Date: Fri, 7 Nov 2025 16:28:30 +0100 Subject: [PATCH 3/3] fix: remove point --- apps/docs/analytics/schema-reference.mdx | 2 -- 1 file changed, 2 deletions(-) diff --git a/apps/docs/analytics/schema-reference.mdx b/apps/docs/analytics/schema-reference.mdx index ab3b1027b5..41d3394a93 100644 --- a/apps/docs/analytics/schema-reference.mdx +++ b/apps/docs/analytics/schema-reference.mdx @@ -291,8 +291,6 @@ WHERE time >= 1704067200000 -- Jan 1, 2024 00:00:00 UTC 3. **Limit result sets** - Add LIMIT clauses to prevent large results 4. **Filter before grouping** - Use WHERE instead of HAVING when possible 5. **Avoid SELECT \*** - Only select columns you need -6. **No need to filter workspace_id** - This is handled automatically based on your authentication - ## Query Limits | Resource | Limit | Error Code |