{"record":{"id":"8934c1378fc9b5c0","repo":"SonarSource/sonarqube","slug":"no-column-has-been-defined-8934c1","errorCode":null,"errorMessage":"No column has been defined","messagePattern":"No column has been defined","errorType":"exception","errorClass":"java.lang.IllegalStateException","httpStatus":null,"severity":"error","filePath":"server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/sql/AlterColumnsBuilder.java","lineNumber":67,"sourceCode":"  private final Dialect dialect;\n  private final String tableName;\n  private final List<ColumnDef> columnDefs = newArrayList();\n\n  public AlterColumnsBuilder(Dialect dialect, String tableName) {\n    this.dialect = dialect;\n    this.tableName = validateTableName(tableName);\n  }\n\n  public AlterColumnsBuilder updateColumn(ColumnDef columnDef) {\n    // limitation of Oracle, only attribute changes must be defined in ALTER.\n    checkArgument(columnDef.getDefaultValue()==null, \"Default value is not supported on alter of column '%s'\", columnDef.getName());\n    columnDefs.add(columnDef);\n    return this;\n  }\n\n  public List<String> build() {\n    if (columnDefs.isEmpty()) {\n      throw new IllegalStateException(\"No column has been defined\");\n    }\n    switch (dialect.getId()) {\n      case PostgreSql.ID:\n        return createPostgresQuery();\n      case Oracle.ID:\n        return createOracleQuery();\n      default:\n        return createMsSqlAndH2Queries();\n    }\n  }\n\n  private List<String> createPostgresQuery() {\n    StringBuilder sql = new StringBuilder(ALTER_TABLE + tableName + \" \");\n    for (Iterator<ColumnDef> columnDefIterator = columnDefs.iterator(); columnDefIterator.hasNext();) {\n      ColumnDef columnDef = columnDefIterator.next();\n      sql.append(ALTER_COLUMN);\n      addColumn(sql, columnDef, \"TYPE \", false);\n      sql.append(\", \");","sourceCodeStart":49,"sourceCodeEnd":85,"githubUrl":"https://github.com/SonarSource/sonarqube/blob/184c821202192afc1c599fc912d0889b69fffa53/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/sql/AlterColumnsBuilder.java#L49-L85","documentation":"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.","triggerScenarios":"build() invoked on an AlterColumnsBuilder with no addColumn(...) calls, typically in a migration that alters existing column types.","commonSituations":"Migration code where a loop over columns to alter yielded nothing; forgotten addColumn call; condition that excluded all columns.","solutions":["Call addColumn(...) for each column to alter before build().","Skip the whole alter step when there is nothing to alter, instead of building an empty builder."],"exampleFix":"// before\nAlterColumnsBuilder b = new AlterColumnsBuilder(dialect, \"users\");\nList<String> sqls = b.build();\n// after\nAlterColumnsBuilder b = new AlterColumnsBuilder(dialect, \"users\");\nb.addColumn(newBigIntColumnDefBuilder().setColumnName(\"created_at\").setIsNull(true).build());\nList<String> sqls = b.build();","handlingStrategy":"validation","validationCode":"if (columnsToAlter.length == 0) { return; } // don't build","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Collect columns first; construct the builder only if the list is non-empty","Never construct builders inside loops that may iterate zero times","Unit-test migrations against both populated and empty column sets"],"tags":["database","migration","sql-builder"],"backgroundTag":"empty-required-field","analyzedSha":"184c821202192afc1c599fc912d0889b69fffa53","analyzedAt":"2026-09-09T12:23:51.573Z","contentChangedAt":"2026-09-09T12:23:51.573Z","schemaVersion":2},"datasetVersion":"2026-09-17T15:17:12.973Z"}