SonarSource/sonarqube · error · java.lang.IllegalStateException

No column has been defined

Error message

No column has been defined

What it means

Thrown by AlterColumnsBuilder.build() when no column definitions were added before generating ALTER TABLE statements. The builder converts column defs into dialect-specific 'ALTER COLUMN'/'MODIFY' SQL and cannot produce anything with zero columns.

Solutions

  1. Call addColumn(...) for each column to alter before build().
  2. Skip the whole alter step when there is nothing to alter, instead of building an empty builder.

Example fix

// before
AlterColumnsBuilder b = new AlterColumnsBuilder(dialect, "users");
List<String> sqls = b.build();
// after
AlterColumnsBuilder b = new AlterColumnsBuilder(dialect, "users");
b.addColumn(newBigIntColumnDefBuilder().setColumnName("created_at").setIsNull(true).build());
List<String> sqls = b.build();
Defensive patterns

Strategy: validation

Validate before calling

if (columnsToAlter.length == 0) { return; } // don't build

Prevention

When it happens

Trigger: build() invoked on an AlterColumnsBuilder with no addColumn(...) calls, typically in a migration that alters existing column types.

Common situations: Migration code where a loop over columns to alter yielded nothing; forgotten addColumn call; condition that excluded all columns.

Understand the failure class

Background: "must not be empty", "cannot be empty" — required-field validation errors across open-source libraries — this error's family across 41 libraries.

Related errors


AI-assisted analysis of SonarSource/sonarqube@184c821202 (2026-09-09). Data as JSON: /api/errors/8934c1378fc9b5c0. Report an issue: GitHub.

Appendix: source

Thrown at server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/sql/AlterColumnsBuilder.java:67

  private final Dialect dialect;
  private final String tableName;
  private final List<ColumnDef> columnDefs = newArrayList();

  public AlterColumnsBuilder(Dialect dialect, String tableName) {
    this.dialect = dialect;
    this.tableName = validateTableName(tableName);
  }

  public AlterColumnsBuilder updateColumn(ColumnDef columnDef) {
    // limitation of Oracle, only attribute changes must be defined in ALTER.
    checkArgument(columnDef.getDefaultValue()==null, "Default value is not supported on alter of column '%s'", columnDef.getName());
    columnDefs.add(columnDef);
    return this;
  }

  public List<String> build() {
    if (columnDefs.isEmpty()) {
      throw new IllegalStateException("No column has been defined");
    }
    switch (dialect.getId()) {
      case PostgreSql.ID:
        return createPostgresQuery();
      case Oracle.ID:
        return createOracleQuery();
      default:
        return createMsSqlAndH2Queries();
    }
  }

  private List<String> createPostgresQuery() {
    StringBuilder sql = new StringBuilder(ALTER_TABLE + tableName + " ");
    for (Iterator<ColumnDef> columnDefIterator = columnDefs.iterator(); columnDefIterator.hasNext();) {
      ColumnDef columnDef = columnDefIterator.next();
      sql.append(ALTER_COLUMN);
      addColumn(sql, columnDef, "TYPE ", false);
      sql.append(", ");

View on GitHub (pinned to 184c821202)