cube-js/cube · error · Error

Index SQL support is not implemented

Error message

Index SQL support is not implemented

What it means

When generating DDL for a pre-aggregation (create table), an index definition can specify either SQL (index.sql) or columns (index.columns). If neither is usable — here, index.columns was falsy so the SQL-building branch ran but createIndexSql path only supports explicit columns — BaseQuery throws 'Index SQL support is not implemented' because the generic adapter cannot render that index form.

Source

Thrown at packages/cubejs-schema-compiler/src/adapter/BaseQuery.js:4410

  preAggregationLoadSql(cube, preAggregation, tableName) {
    const sqlAndParams = this.preAggregationSql(cube, preAggregation);
    return [`CREATE TABLE ${tableName} ${this.asSyntaxTable} ${sqlAndParams[0]}`, sqlAndParams[1]];
  }

  preAggregationPreviewSql(tableName) {
    return this.paramAllocator.buildSqlAndParams(`SELECT * FROM ${tableName} LIMIT 1000`);
  }

  indexSql(cube, preAggregation, index, indexName, tableName) {
    if (preAggregation.external && this.externalQueryClass) {
      return this.externalQuery().indexSql(cube, preAggregation, index, indexName, tableName);
    }

    if (index.columns) {
      const escapedColumns = this.evaluateIndexColumns(cube, index);
      return this.paramAllocator.buildSqlAndParams(this.createIndexSql(indexName, tableName, escapedColumns));
    } else {
      throw new Error('Index SQL support is not implemented');
    }
  }

  evaluateIndexColumns(cube, index) {
    const columns = this.cubeEvaluator.evaluateReferences(cube, index.columns, { originalSorting: true });
    return columns.map(column => {
      const path = column.split('.');
      if (path[0] &&
        this.cubeEvaluator.cubeExists(path[0]) &&
        (
          this.cubeEvaluator.isMeasure(path) ||
          this.cubeEvaluator.isDimension(path) ||
          this.cubeEvaluator.isSegment(path)
        )
      ) {
        if (path.length === 3 && this.cubeEvaluator.isDimension(path.slice(0, 2))) {
          const dimensionDef = this.cubeEvaluator.dimensionByPath(path.slice(0, 2));
          if (dimensionDef.type === 'time' &&

View on GitHub (pinned to 7d981676b3)

Solutions

  1. Add the `columns:` array (list of dimension/measure member names) to the index definition
  2. Verify the index definition references valid member names so evaluateReferences yields columns
  3. Remove the index from the pre-aggregation if not needed

Example fix

// before
indexes:
  main:
    name: main_idx
// after
indexes:
  main:
    name: main_idx
    columns:
      - created_at
      - city
Defensive patterns

Strategy: validation

Validate before calling

for (const [name, idx] of Object.entries(cubeDef.preAggregations?.[0]?.indexes || {})) {
  if (!idx.columns?.length && !idx.sql) throw new Error(`Index '${name}' must define columns (array of member names)`);
}

Type guard

function indexHasColumns(index) {
  return typeof index === 'object' && index !== null &&
    Array.isArray(index.columns) && index.columns.length > 0;
}

Try / catch

try { await compiler.compile(); } catch (e) {
  if (/Index SQL support is not implemented/.test(e.message)) {
    throw new Error('Pre-aggregation index must declare columns: [...]');
  }
  throw e;
}

Prevention

When it happens

Trigger: Defining a pre-aggregation index without a columns attribute (or with columns that evaluate to nothing), so index.columns is missing when Cube builds the CREATE INDEX statement.

Common situations: YAML/JS preAggregation indexes written with only a name or sql field instead of columns; renaming/refactoring index definitions so `columns:` was dropped.

Related errors


AI-assisted analysis of cube-js/cube@7d981676b3 (2026-09-02). Data as JSON: /api/errors/ca36cf986a3cd07f. Report an issue: GitHub.