{"record":{"id":"b5571232f6daa15b","repo":"OtterMind/Chat2DB","slug":"source-table-ddl-is-empty","errorCode":null,"errorMessage":"Source table DDL is empty","messagePattern":"Source table DDL is empty","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"chat2db-community-server/chat2db-community-plugins/chat2db-community-sqlserver/src/main/java/ai/chat2db/plugin/sqlserver/SqlServerDBManager.java","lineNumber":252,"sourceCode":"            String columnList = String.join(\", \", copyableColumns);\n            String sourceTable = buildFullTableName(databaseName, schemaName, tableName);\n            String targetTable = buildFullTableName(databaseName, schemaName, newTableName);\n            String insertSql = buildCopyDataSql(targetTable, columnList, sourceTable);\n            log.info(\"copy table data sql: {}\", insertSql);\n\n            if (hasIdentity) {\n                executeIdentityCopy(targetTable, insertSql,\n                        sql -> DefaultSQLExecutor.getInstance().execute(connection, sql, resultSet -> null));\n            } else {\n                DefaultSQLExecutor.getInstance().execute(connection, insertSql, resultSet -> null);\n            }\n        }\n    }\n\n    static List<String> prepareCopyDdlBatches(String ddl, String databaseName, String schemaName,\n            String tableName, String newTableName) {\n        if (StringUtils.isBlank(ddl)) {\n            throw new IllegalArgumentException(\"Source table DDL is empty\");\n        }\n\n        List<String> sourceReferences = tableReferences(databaseName, schemaName, tableName);\n        String targetTable = buildFullTableName(null, schemaName, newTableName);\n        List<String> rewrittenBatches = new ArrayList<>();\n        boolean createTableRewritten = false;\n\n        for (String batch : splitDdlBatches(ddl)) {\n            String rewritten = batch;\n            if (startsWithKeyword(batch, \"CREATE\\\\s+TABLE\")) {\n                rewritten = replaceObjectAfterKeyword(batch, \"CREATE\\\\s+TABLE\\\\s+\", sourceReferences,\n                        targetTable);\n                rewritten = rewriteSelfReference(rewritten, sourceReferences, tableName, targetTable);\n                // Constraint names are schema-scoped, so copied declarations must receive fresh server-generated names.\n                rewritten = removeNamedTableConstraints(rewritten);\n                createTableRewritten = true;\n            } else if (CREATE_INDEX_BATCH.matcher(batch).find()) {\n                rewritten = replaceObjectAfterKeyword(batch, \"ON\\\\s+\", sourceReferences, targetTable);","sourceCodeStart":234,"sourceCodeEnd":270,"githubUrl":"https://github.com/OtterMind/Chat2DB/blob/5ee1e990e73fbcae1969dc554be254fedb3ab888/chat2db-community-server/chat2db-community-plugins/chat2db-community-sqlserver/src/main/java/ai/chat2db/plugin/sqlserver/SqlServerDBManager.java#L234-L270","documentation":"Thrown by SqlServerDBManager.prepareCopyDdlBatches (the table-copy feature) when the supplied source-table DDL string is null or blank. The method rewrites a CREATE TABLE script to target a new table name, so it needs a non-empty DDL to start from.","triggerScenarios":"Invoking the copy-table flow when the source table's DDL could not be fetched (returned null/empty) - e.g. the DB metadata query for the original CREATE TABLE returned nothing, or the caller passed an empty string.","commonSituations":"The source object is a view/Synonym/temp table whose DDL isn't exposed the same way; permissions prevent reading the definition; an upstream metadata service returned an empty body; the table was dropped between fetch and copy.","solutions":["Fetch and verify a non-empty DDL for the source table before calling prepareCopyDdlBatches.","Confirm the connected user has VIEW DEFINITION permission on the source table.","Handle a null/empty DDL upstream as a user-facing 'cannot copy: definition unavailable' message rather than letting it throw."],"exampleFix":"// before\nString ddl = fetchDdl(table); // returned \"\"\nprepareCopyDdlBatches(ddl, db, schema, table, newTable);\n// -> Source table DDL is empty\n\n// after\nString ddl = fetchDdl(table);\nif (StringUtils.isBlank(ddl)) {\n    throw new IllegalStateException(\"No DDL available for \" + table);\n}\nprepareCopyDdlBatches(ddl, db, schema, table, newTable);","handlingStrategy":"validation","validationCode":"if (StringUtils.isBlank(ddl)) {\n    throw new IllegalStateException(\"Cannot copy table: source DDL is unavailable\");\n}","typeGuard":null,"tryCatchPattern":"try {\n    prepareCopyDdlBatches(ddl, db, schema, table, newTable);\n} catch (IllegalArgumentException e) {\n    // surface a user-facing 'definition unavailable' message\n    log.warn(\"Table copy aborted for {}: {}\", table, e.getMessage());\n}","preventionTips":["Verify VIEW DEFINITION permission for the source table.","Fetch and check DDL non-emptiness before invoking the copy flow.","Handle unsupported object kinds (views, synonyms) before copying."],"tags":["sqlserver","ddl","table-copy","validation"],"backgroundTag":null,"analyzedSha":"5ee1e990e73fbcae1969dc554be254fedb3ab888","analyzedAt":"2026-08-14T07:05:03.077Z","schemaVersion":2},"datasetVersion":"2026-08-14T10:17:34.591Z"}