{"record":{"id":"db6ffe5f251d7ef7","repo":"OtterMind/Chat2DB","slug":"unable-to-rewrite-source-table-reference-in-ddl-ba","errorCode":null,"errorMessage":"Unable to rewrite source table reference in DDL batch: {sql}","messagePattern":"Unable to rewrite source table reference in DDL batch: (.+?)","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":379,"sourceCode":"\n    private static boolean isExtendedPropertyBatch(String sql) {\n        return Pattern.compile(\"(?is)^\\\\s*exec\\\\s+sp_addextendedproperty\\\\b\").matcher(sql).find();\n    }\n\n    private static String replaceObjectAfterKeyword(String sql, String keywordPattern, List<String> sourceReferences,\n            String targetReference) {\n        String alternatives = sourceReferences.stream()\n                .map(Pattern::quote)\n                .collect(Collectors.joining(\"|\"));\n        Pattern pattern = Pattern.compile(\"(?i)(\\\\b\" + keywordPattern + \")(?:(?:\" + alternatives + \"))\");\n        Matcher matcher = pattern.matcher(sql);\n        while (matcher.find()) {\n            if (isSqlCodeAt(sql, matcher.start())) {\n                return sql.substring(0, matcher.start()) + matcher.group(1) + targetReference\n                        + sql.substring(matcher.end());\n            }\n        }\n        throw new IllegalArgumentException(\"Unable to rewrite source table reference in DDL batch: \" + sql);\n    }\n\n    private static String rewriteSelfReference(String sql, List<String> sourceReferences, String tableName,\n            String targetReference) {\n        Set<String> references = new LinkedHashSet<>(sourceReferences);\n        references.add(quoteIdentifier(tableName));\n        references.add(tableName);\n        String alternatives = references.stream()\n                .filter(StringUtils::isNotBlank)\n                .map(Pattern::quote)\n                .collect(Collectors.joining(\"|\"));\n        Pattern pattern = Pattern.compile(\"(?i)(\\\\breferences\\\\s+)(?:(?:\" + alternatives + \"))(?=\\\\s*\\\\()\");\n        Matcher matcher = pattern.matcher(sql);\n        StringBuffer rewritten = new StringBuffer();\n        while (matcher.find()) {\n            if (isSqlCodeAt(sql, matcher.start())) {\n                matcher.appendReplacement(rewritten, Matcher.quoteReplacement(matcher.group(1) + targetReference));\n            }","sourceCodeStart":361,"sourceCodeEnd":397,"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#L361-L397","documentation":"Thrown by SqlServerDBManager.replaceObjectAfterKeyword when the regex built from the keyword pattern plus the source-table reference alternatives finds no in-code match anywhere in the given DDL batch. It walks all matches and returns on the first that sits in executable code (isSqlCodeAt); if none qualifies, it cannot perform the rewrite and fails.","triggerScenarios":"During table-copy DDL rewriting, a batch identified as needing retargeting (e.g. an 'ON <filegroup>' clause or CREATE TABLE) does not contain the expected source table reference token, or the only occurrences are inside comments/quoted identifiers and thus excluded by isSqlCodeAt.","commonSituations":"The source table reference uses an unexpected qualification (3-part vs 2-part name) not present in sourceReferences; the reference is entirely inside a comment or bracketed identifier; the batch was misclassified as needing rewrite.","solutions":["Verify the sourceReferences list passed in covers every form the DDL uses (e.g. [db].[schema].[table], [schema].[table], [table]).","Check that the relevant token is not solely inside a comment or quoted identifier (isSqlCodeAt excludes those).","If the batch genuinely does not reference the source table, exclude it from the rewrite set rather than forcing a match."],"exampleFix":"// before: sourceReferences only had \"[dbo].[t]\" but DDL uses \"[t]\"\nreplaceObjectAfterKeyword(batch, \"ON\\\\s+\", List.of(\"[dbo].[t]\"), target);\n// -> Unable to rewrite source table reference in DDL batch\n\n// after: include all qualification forms\nreplaceObjectAfterKeyword(batch, \"ON\\\\s+\",\n    tableReferences(db, schema, tableName), target);","handlingStrategy":"validation","validationCode":"// Build the full set of reference forms the DDL might use\nList<String> refs = tableReferences(databaseName, schemaName, tableName);\n// Confirm at least one appears in code (not comment/quoted) before rewriting\nboolean any = batches.stream().anyMatch(b -> refs.stream().anyMatch(r -> inCodeContains(b, r)));\nif (!any) throw new IllegalStateException(\"No rewritable source reference\");","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Pass all qualification forms (2-part and 3-part) in sourceReferences.","Exclude batches that do not reference the source table from rewrite.","Check isSqlCodeAt for occurrences trapped in comments/identifiers."],"tags":["sqlserver","ddl","table-copy","parsing"],"backgroundTag":null,"analyzedSha":"5ee1e990e73fbcae1969dc554be254fedb3ab888","analyzedAt":"2026-08-14T07:05:03.077Z","schemaVersion":2},"datasetVersion":"2026-08-14T10:17:34.591Z"}