OtterMind/Chat2DB · error · IllegalArgumentException

Unable to locate the source CREATE TABLE statement

Error message

Unable to locate the source CREATE TABLE statement

What it means

Thrown by SqlServerDBManager.prepareCopyDdlBatches when, after splitting and rewriting each DDL batch, no batch was recognized as the source CREATE TABLE statement (the flag createTableRewritten stayed false). The rewriter only flips that flag when a batch matches the 'CREATE\s+TABLE' keyword prefix and is successfully retargeted.

Source

Thrown at chat2db-community-server/chat2db-community-plugins/chat2db-community-sqlserver/src/main/java/ai/chat2db/plugin/sqlserver/SqlServerDBManager.java:282

                        targetTable);
                rewritten = rewriteSelfReference(rewritten, sourceReferences, tableName, targetTable);
                // Constraint names are schema-scoped, so copied declarations must receive fresh server-generated names.
                rewritten = removeNamedTableConstraints(rewritten);
                createTableRewritten = true;
            } else if (CREATE_INDEX_BATCH.matcher(batch).find()) {
                rewritten = replaceObjectAfterKeyword(batch, "ON\\s+", sourceReferences, targetTable);
            } else if (isExtendedPropertyBatch(batch)) {
                if (CONSTRAINT_COMMENT.matcher(batch).find()) {
                    // Auto-generated target constraint names cannot be addressed by the source constraint comment.
                    continue;
                }
                rewritten = rewriteExtendedPropertyTable(batch, tableName, newTableName);
            }
            rewrittenBatches.add(rewritten.trim());
        }

        if (!createTableRewritten) {
            throw new IllegalArgumentException("Unable to locate the source CREATE TABLE statement");
        }
        return rewrittenBatches;
    }

    static List<String> splitDdlBatches(String ddl) {
        List<String> batches = new ArrayList<>();
        StringBuilder batch = new StringBuilder();
        DdlLexicalState state = new DdlLexicalState();
        String[] lines = ddl.split("\\R", -1);
        for (String line : lines) {
            if (state.isCode()) {
                if (GO_BATCH_LINE.matcher(line).matches()) {
                    addBatch(batches, batch);
                    continue;
                }
                Matcher inlineBatch = GO_EXTENDED_PROPERTY_LINE.matcher(line);
                if (inlineBatch.matches()) {
                    addBatch(batches, batch);

View on GitHub (pinned to 5ee1e990e7)

Solutions

  1. Inspect the split batches (splitDdlBatches) to confirm a batch literally begins with 'CREATE TABLE'.
  2. Ensure the DDL is the raw CREATE TABLE script, not a wrapped/sp_help-style report.
  3. If the DDL legitimately lacks a CREATE TABLE batch, surface a 'cannot copy: definition not in expected form' error instead of relying on the implicit throw.

Example fix

// before: ddl only had ALTER/extended-property batches, no CREATE TABLE
prepareCopyDdlBatches(ddl, ...);
// -> Unable to locate the source CREATE TABLE statement

// after
List<String> batches = splitDdlBatches(ddl);
boolean hasCreate = batches.stream().anyMatch(b -> startsWithKeyword(b, "CREATE\\s+TABLE"));
if (!hasCreate) {
    throw new IllegalStateException("Source DDL has no CREATE TABLE batch");
}
prepareCopyDdlBatches(ddl, ...);
Defensive patterns

Strategy: validation

Validate before calling

List<String> batches = splitDdlBatches(ddl);
boolean hasCreate = batches.stream().anyMatch(b -> startsWithKeyword(b, "CREATE\\s+TABLE"));
if (!hasCreate) {
    throw new IllegalStateException("Source DDL has no CREATE TABLE batch");
}

Prevention

When it happens

Trigger: The supplied DDL, after batch splitting (on GO / lexical state), contains no batch beginning with 'CREATE TABLE'. This happens when the DDL is entirely extended properties/constraints/indexes, when the CREATE keyword is inside a comment or string so the lexical scanner treats it as code-free, or when the statement uses a different phrasing.

Common situations: Source definition returned only secondary objects; a tool exports DDL with the CREATE TABLE wrapped or commented; GO-batch splitting mis-segmented a multi-statement batch; case/comment edge cases in the DdlLexicalState scanner.

Related errors


AI-assisted analysis of OtterMind/Chat2DB@5ee1e990e7 (2026-08-14). Data as JSON: /api/errors/fcd1161164cc90d6. Report an issue: GitHub.