Skip to content

Tesseract SQL planner emits Postgres $n::timestamptz placeholders in CubeStore rollup_lambda read, causing No field named "$1" #10870

@scestrade

Description

@scestrade

Describe the bug

When querying a rollup_lambda pre-aggregation with Tesseract enabled, Cube can generate top-level CubeStore SQL that contains Postgres-style positional placeholders such as $1::timestamptz.

CubeStore/DataFusion appears to parse $1 as an identifier/field instead of a bind parameter, and the query fails with:

Error: Internal: Schema error: No field named "$1"

This happens on the top-level external pre-aggregation read. The source/lambda SQL can correctly use Postgres placeholders, but the CubeStore-side SQL appears to need CubeStore-compatible placeholders, e.g. ? / to_timestamp(?).

To Reproduce

  1. Run Cube 1.6.45 with:
CUBEJS_DEV_MODE=false
CUBEJS_TESSERACT_SQL_PLANNER=true
CUBEJS_TESSERACT_PRE_AGGREGATIONS=true
  1. Define a cube with a partitioned rollup and a rollup_lambda that uses union_with_source_data: true.

  2. Build at least part of the rollup range, then query a date range that causes Cube to read the built rollup plus the live source/lambda tail.

  3. Query example:

{
  "measures": ["Orders.totalAmount"],
  "timeDimensions": [
    {
      "dimension": "Orders.completedAt",
      "dateRange": ["2026-04-01T00:00:00.000Z", "2026-05-12T23:59:59.999Z"]
    }
  ]
}
  1. The generated /sql response contains a top-level external CubeStore query shaped like:
SELECT ...
FROM prod_pre_aggregations.orders_summary...
WHERE ("orders__completed_at_day" >= $1::timestamptz
  AND "orders__completed_at_day" <= $2::timestamptz)
  1. /load fails with:
Error: Internal: Schema error: No field named "$1"

Expected behavior

The top-level CubeStore/external pre-aggregation SQL should use placeholder syntax that CubeStore can parse as bind parameters.

For example, instead of:

"orders__completed_at_day" >= $1::timestamptz

the external CubeStore read should emit something equivalent to:

"orders__completed_at_day" >= to_timestamp(?)

or otherwise avoid sending Postgres $n::timestamptz placeholders to CubeStore.

Screenshots

Not applicable.

Minimally reproducible Cube Schema

This is a reduced version of the pattern. The important pieces are CUBEJS_TESSERACT_SQL_PLANNER=true, CUBEJS_TESSERACT_PRE_AGGREGATIONS=true, a partitioned rollup, and a rollup_lambda with union_with_source_data: true.

cube(`Orders`, {
  sql: `
    SELECT
      1 AS id,
      100 AS amount,
      timestamp '2026-04-01 10:00:00' AS completed_at
    UNION ALL
    SELECT
      2 AS id,
      200 AS amount,
      timestamp '2026-05-12 10:00:00' AS completed_at
  `,

  measures: {
    count: {
      type: `count`,
    },

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions