Describe the bug
When a CubeSQL query contains a nested aggregate function inside MEASURE() — e.g., MEASURE(SUM(column)) — the query planner spins the CPU for 30-60 seconds before eventually returning an error. During this time, the single-threaded Cube process is completely blocked and cannot serve any other requests.
The correct syntax is either MEASURE(column) or SUM(column) — these are alternatives, not composable. However, instead of immediately rejecting the invalid nesting with a parse/validation error, Cube attempts to build a physical plan and gets stuck in an expensive planning loop.
Expected behavior
MEASURE(SUM(...)) (and similar nesting like MEASURE(COUNT(...)), MEASURE(AVG(...)), etc.) should be rejected immediately during SQL parsing or logical plan validation — ideally in under 100ms — with a clear error message like:
"Nested aggregate functions inside MEASURE() are not supported. Use MEASURE(column) or SUM(column), not MEASURE(SUM(column))."
Actual behavior
Cube spins the CPU for 30-60 seconds, blocking all concurrent requests, then returns:
This feature is not implemented: Physical plan does not support logical expression SUM(#ItemSales.sales_quantity)
The duration field in the error log confirms the excessive time (e.g., "duration": 64902 — nearly 65 seconds for a query that never reaches the database).
To Reproduce
Data model (YAML)
cubes:
- name: ItemSales
sql: "SELECT * FROM some_table"
dimensions:
- name: item_name
sql: "{CUBE}.item_name"
type: string
- name: local_date
sql: "{CUBE}.local_date"
type: time
- name: check_state
sql: "{CUBE}.check_state"
type: string
measures:
- name: sales_quantity
sql: "CASE WHEN {CUBE}.transaction_type = 'SALE' THEN {CUBE}.quantity ELSE 0 END"
type: sum
Query (via SQL API — REST or Postgres wire protocol)
SELECT
ItemSales.item_name,
MEASURE(SUM(ItemSales.sales_quantity)) AS total_quantity
FROM ItemSales
WHERE ItemSales.local_date >= '2026-01-11'
AND ItemSales.local_date <= '2026-04-10'
AND ItemSales.check_state = 'CLOSED_CHECK'
GROUP BY
ItemSales.item_name
HAVING MEASURE(SUM(ItemSales.sales_quantity)) > 0
ORDER BY total_quantity DESC
LIMIT 20
Expected result
Immediate error (< 1 second) rejecting the query.
Actual result
~30-65 second hang, then:
{
"error": "This feature is not implemented: Physical plan does not support logical expression SUM(#ItemSales.sales_quantity)"
}
Impact
This is an availability/DoS concern. Because Cube's query planner is single-threaded, a single MEASURE(SUM(...)) query blocks all other traffic for 30-60 seconds. In our production environment, a client submitted ~34 such queries in rapid succession, causing a sustained outage where no other requests could be served.
We've added a workaround on our API gateway layer to reject these patterns with a 400 before they reach Cube, but this should ideally be handled in Cube itself — both the immediate rejection and preventing the CPU spin.
Additional context
The table of valid aggregate functions from the Cube SQL API docs confirms that MEASURE(column) and SUM(column) are alternatives for sum-type measures. The docs do not document MEASURE(SUM(...)) as valid syntax, and the error confirms it isn't — the issue is purely that the rejection path is catastrophically slow.
| Measure type |
Valid aggregate functions |
| sum |
MEASURE or SUM |
| count |
MEASURE or COUNT |
| avg |
MEASURE or AVG |
| min |
MEASURE or MIN |
| max |
MEASURE or MAX |
None of these support nesting (e.g., MEASURE(SUM(...)), MEASURE(COUNT(...))).
Describe the bug
When a CubeSQL query contains a nested aggregate function inside
MEASURE()— e.g.,MEASURE(SUM(column))— the query planner spins the CPU for 30-60 seconds before eventually returning an error. During this time, the single-threaded Cube process is completely blocked and cannot serve any other requests.The correct syntax is either
MEASURE(column)orSUM(column)— these are alternatives, not composable. However, instead of immediately rejecting the invalid nesting with a parse/validation error, Cube attempts to build a physical plan and gets stuck in an expensive planning loop.Expected behavior
MEASURE(SUM(...))(and similar nesting likeMEASURE(COUNT(...)),MEASURE(AVG(...)), etc.) should be rejected immediately during SQL parsing or logical plan validation — ideally in under 100ms — with a clear error message like:Actual behavior
Cube spins the CPU for 30-60 seconds, blocking all concurrent requests, then returns:
The
durationfield in the error log confirms the excessive time (e.g.,"duration": 64902— nearly 65 seconds for a query that never reaches the database).To Reproduce
Data model (YAML)
Query (via SQL API — REST or Postgres wire protocol)
Expected result
Immediate error (< 1 second) rejecting the query.
Actual result
~30-65 second hang, then:
{ "error": "This feature is not implemented: Physical plan does not support logical expression SUM(#ItemSales.sales_quantity)" }Impact
This is an availability/DoS concern. Because Cube's query planner is single-threaded, a single
MEASURE(SUM(...))query blocks all other traffic for 30-60 seconds. In our production environment, a client submitted ~34 such queries in rapid succession, causing a sustained outage where no other requests could be served.We've added a workaround on our API gateway layer to reject these patterns with a 400 before they reach Cube, but this should ideally be handled in Cube itself — both the immediate rejection and preventing the CPU spin.
Additional context
The table of valid aggregate functions from the Cube SQL API docs confirms that
MEASURE(column)andSUM(column)are alternatives forsum-type measures. The docs do not documentMEASURE(SUM(...))as valid syntax, and the error confirms it isn't — the issue is purely that the rejection path is catastrophically slow.MEASUREorSUMMEASUREorCOUNTMEASUREorAVGMEASUREorMINMEASUREorMAXNone of these support nesting (e.g.,
MEASURE(SUM(...)),MEASURE(COUNT(...))).