Filed while fixing #13714 (analytics time-dimension granularity 500). Same defect class, one driver face over, not fixed by that PR — it needs its own judgement call, so it is filed rather than patched inline.
What
RemoteTransport.aggregate (Turso remote mode) holds the aggregation alias to SAFE_IDENTIFIER:
const SAFE_IDENTIFIER = /^[a-zA-Z_][a-zA-Z0-9_]*$/; // remote-transport.ts:71
...
const alias = agg.alias || `${func}_${field === '*' ? 'all' : field}`;
this.assertSafeIdentifier(alias);
selectParts.push(`${lowering.sql}(${argSql}) AS "${alias}"`);
A dot fails that regex. Every analytics measure is addressed as CUBE.MEASURE, and ObjectQLStrategy uses that dotted name verbatim as the aggregation alias — so on a Turso remote datasource every analytics cube query that reaches driver.aggregate throws:
RemoteTransport: unsafe identifier rejected: "showcase_delivery.count"
a bare Error with no code and no status, which mapDataError then serves as an opaque 500 — the #11455 / #8931 shape this repo has been closing door by door.
Why it is a defect and not the guard doing its job
The alias is written into a double-quoted identifier (AS "${alias}"), where a dot is inert and legal SQL. AggregationNodeSchema declares alias: z.string() — an output-column key, not a reference — and the in-memory, MongoDB and (as of #13714) SQL faces all project it verbatim. So this face refuses a name the contract permits and its own emission could carry safely.
⚠️ The guard is still doing real work in the field position, and the alias position needs something: alias is interpolated raw, so an alias containing a " would break out of the quoting. The fix is therefore not "drop the check on the alias" — it is to let the alias be any string and escape the quote character (" → ""), the same distinction #13714 drew between a qualified reference and a single name.
Reproduction sketch
Point an analytics cube at a Turso remote datasource and run any cube query (measures: ["some_cube.count"]). Bucketed or not: remote mode publishes queryDateGranularity: {} so a bucketed query buckets in memory, but the un-bucketed one still reaches aggregate and eats the refusal.
Scope note
Local-file Turso mode inherits SqlDriver and is covered by #13714's repair; this is the remote transport's own hand-written SQL face only.
Filed while fixing #13714 (analytics time-dimension granularity 500). Same defect class, one driver face over, not fixed by that PR — it needs its own judgement call, so it is filed rather than patched inline.
What
RemoteTransport.aggregate(Turso remote mode) holds the aggregationaliastoSAFE_IDENTIFIER:A dot fails that regex. Every analytics measure is addressed as
CUBE.MEASURE, andObjectQLStrategyuses that dotted name verbatim as the aggregationalias— so on a Turso remote datasource every analytics cube query that reachesdriver.aggregatethrows:a bare
Errorwith nocodeand nostatus, whichmapDataErrorthen serves as an opaque 500 — the #11455 / #8931 shape this repo has been closing door by door.Why it is a defect and not the guard doing its job
The alias is written into a double-quoted identifier (
AS "${alias}"), where a dot is inert and legal SQL.AggregationNodeSchemadeclaresalias: z.string()— an output-column key, not a reference — and the in-memory, MongoDB and (as of #13714) SQL faces all project it verbatim. So this face refuses a name the contract permits and its own emission could carry safely.fieldposition, and the alias position needs something:aliasis interpolated raw, so an alias containing a"would break out of the quoting. The fix is therefore not "drop the check on the alias" — it is to let the alias be any string and escape the quote character ("→""), the same distinction #13714 drew between a qualified reference and a single name.Reproduction sketch
Point an analytics cube at a Turso remote datasource and run any cube query (
measures: ["some_cube.count"]). Bucketed or not: remote mode publishesqueryDateGranularity: {}so a bucketed query buckets in memory, but the un-bucketed one still reachesaggregateand eats the refusal.Scope note
Local-file Turso mode inherits
SqlDriverand is covered by #13714's repair; this is the remote transport's own hand-written SQL face only.