OtterMind/Chat2DB · error · BusinessException
copy table error
copy table error
Error message
copy table error
What it means
Thrown by DbTableServiceImpl.copyTable when the underlying IDbManager.copyTable call fails. The service first builds a new table name (defaulting to '<table>_copy_<MMddHHmmss>', truncated to 32 chars), resolves both names through the dialect's metadata name, then delegates to the plugin's copyTable implementation. Any exception there is wrapped and rethrown as a generic 'copy table error'.
Source
Thrown at chat2db-community-server/chat2db-community-domain/chat2db-community-domain-core/src/main/java/ai/chat2db/community/domain/core/impl/db/DbTableServiceImpl.java:334
@Override
public void copyTable(DbTableCopyRequest param) {
try {
IDbMetaData metaData = Chat2DBContext.getDbMetaData();
String newName = param.getNewName();
if (StringUtils.isBlank(newName)) {
newName = param.getTableName() + "_copy_" + DateUtil.format(new Date(), "MMddHHmmss");
if (newName.length() > 32) {
newName = newName.substring(0, 32);
}
}
String tableName = metaData.getMetaDataName(param.getTableName());
String newTableName = metaData.getMetaDataName(newName);
Chat2DBContext.getDbManager().copyTable(
Chat2DBContext.getConnection(),
param.getDatabaseName(), param.getSchemaName(), tableName, newTableName, param.isCopyData());
} catch (Exception e) {
log.error("copy table error", e);
throw new BusinessException("copy table error", new Object[]{e.getMessage()}, e);
}
}
private void setPrimaryKey(Table table) {
if (table == null) {
return;
}
List<TableIndex> tableIndices = table.getIndexList();
if (CollectionUtils.isEmpty(tableIndices)) {
return;
}
List<TableColumn> columns = table.getColumnList();
if (CollectionUtils.isEmpty(columns)) {
return;
}
Map<String, TableColumn> columnMap = columns.stream()
.collect(Collectors.toMap(TableColumn::getName, Function.identity()));
List<TableIndex> indexes = new ArrayList<>();View on GitHub (pinned to 5ee1e990e7)
Solutions
- Provide an explicit, unique param.newName that fits the target dialect's identifier rules and length limit instead of relying on the auto-generated truncated name.
- Verify the connected user has CREATE TABLE and (if copyData) INSERT privileges on the target schema.
- Check the server log line 'copy table error' — the wrapped e.getMessage() names the underlying SQL/plugin cause; address that first.
- Confirm the dialect plugin (chat2db-community-plugins) supports copyTable for the selected DB type.
Example fix
// before DbTableCopyRequest param = new DbTableCopyRequest(); // newName left null -> '_copy_<ts>' may truncate past 32 chars // after String safe = param.getTableName(); if (safe.length() > 26) safe = safe.substring(0, 26); param.setNewName(safe + "_copy"); // explicit, within limits
Defensive patterns
Strategy: validation
Validate before calling
// before delegating to copyTable
String name = param.getNewName() != null ? param.getNewName()
: param.getTableName() + "_copy_" + DateUtil.format(new Date(), "MMddHHmmss");
if (name.length() > 32) name = name.substring(0, 32);
if (!name.matches("[A-Za-z_][A-Za-z0-9_]*")) throw new IllegalArgumentException("bad table name: " + name);
// existence/uniqueness check via dbManager before copyTable
Try / catch
try { dbTableService.copyTable(param); }
catch (BusinessException e) {
// e.getArgs()[0] holds the wrapped SQL message
throw new CopyFailedException("copy table failed: " + e.getArgs()[0], e);
} Prevention
- Always pass an explicit, validated newName rather than relying on the auto-generated truncated suffix.
- Confirm target schema CREATE/INSERT privileges before initiating the copy.
- Log the wrapped e.getMessage() to surface the real dialect-level cause.
When it happens
Trigger: POST copyTable with a name that already exists, exceeds the dialect identifier length limit, contains illegal characters, or when the source table cannot be found. Also triggered when the connected DB user lacks CREATE/INSERT privileges, the connection is dropped mid-copy, or the dialect plugin throws on copyData=true for a table with unsupported column types.
Common situations: Auto-generated '_copy_' name collides after the 32-char truncation (e.g. long table name makes the timestamp suffix ambiguous); copying into a schema with existing objects; driver version that does not implement copyTable for the selected DB type.
Related errors
- database.delete.prepareFailed
- database.delete.connectionTargetsDeletedDatabase
- database.delete.executeFailed
- database.delete.connectionDatabaseMismatch
- Source table DDL is empty
AI-assisted analysis of OtterMind/Chat2DB@5ee1e990e7 (2026-08-14).
Data as JSON: /api/errors/8f95e2de468ef5be.
Report an issue: GitHub.