OtterMind/Chat2DB · error · IllegalArgumentException

Unable to rewrite table extended property: {sql}

Error message

Unable to rewrite table extended property: {sql}

What it means

Thrown by SqlServerDBManager.rewriteExtendedPropertyTable when the regex 'TABLE'\s*,\s*N'<tableName>' does not match anywhere in the extended-property batch. Extended properties (sp_addextendedproperty style) carry the table name as a quoted N'...' argument; if the stored name differs from the supplied tableName, the rewrite cannot proceed and fails.

Source

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

            } else if (current == '/' && next == '*') {
                state.blockCommentDepth++;
                i++;
            } else if (current == '\'') {
                state.inString = true;
            } else if (current == '[') {
                inBracketIdentifier = true;
            } else if (current == '"') {
                inQuotedIdentifier = true;
            }
        }
        return !inLineComment && state.isCode() && !inBracketIdentifier && !inQuotedIdentifier;
    }

    private static String rewriteExtendedPropertyTable(String sql, String tableName, String newTableName) {
        Pattern pattern = Pattern.compile("(?i)('TABLE'\\s*,\\s*N')" + Pattern.quote(tableName) + "(')");
        Matcher matcher = pattern.matcher(sql);
        if (!matcher.find()) {
            throw new IllegalArgumentException("Unable to rewrite table extended property: " + sql);
        }
        String replacement = matcher.group(1) + newTableName.replace("'", "''") + matcher.group(2);
        return matcher.replaceFirst(Matcher.quoteReplacement(replacement));
    }

    static boolean isCopyableColumn(String computedDefinition, String dataType) {
        return StringUtils.isBlank(computedDefinition)
                && !"timestamp".equalsIgnoreCase(dataType)
                && !"rowversion".equalsIgnoreCase(dataType);
    }

    static String buildCopyDataSql(String targetTable, String columnList, String sourceTable) {
        return String.format(SQL_COPY_TABLE_DATA_WITH_COLUMNS, targetTable, columnList, columnList, sourceTable);
    }

    static void executeIdentityCopy(String targetTable, String insertSql, Consumer<String> executor) {
        String identityOn = String.format(SQL_SET_IDENTITY_INSERT, targetTable, "ON");
        String identityOff = String.format(SQL_SET_IDENTITY_INSERT, targetTable, "OFF");

View on GitHub (pinned to 5ee1e990e7)

Solutions

  1. Confirm tableName matches the N'...' argument exactly (case-sensitive, including any bracket characters).
  2. Ensure only table-level extended property batches are routed to rewriteExtendedPropertyTable; route column/level-2 batches through their own handler.
  3. If the batch is unrelated, skip it (continue) instead of attempting the rewrite.

Example fix

// before: property stored N'Order_Header' but tableName passed "order_header"
rewriteExtendedPropertyTable(batch, "order_header", "Order_Header_Copy");
// -> Unable to rewrite table extended property

// after: pass the exact stored name
rewriteExtendedPropertyTable(batch, "Order_Header", "Order_Header_Copy");
Defensive patterns

Strategy: validation

Validate before calling

// Confirm the stored table name appears as N'<tableName>' before rewriting
if (!Pattern.compile("(?i)'TABLE'\\s*,\\s*N'" + Pattern.quote(tableName) + "'").matcher(batch).find()) {
    // route elsewhere or skip, do not call rewriteExtendedPropertyTable
}

Prevention

When it happens

Trigger: Processing an extended-property DDL batch whose @value=... or @level1name=N'...' table argument does not contain the exact tableName passed in - e.g. the property references a schema-qualified or differently-cased name, or the batch is a column/level-2 property that has no table-level N'<tableName>' slot.

Common situations: Case/bracketing differences between the metadata table name and the name embedded in the extended property; an extended property batch for a different level (column) reaching the table rewriter; partial DDL export.

Related errors


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