fix: ALTER TABLE DROP COLUMN preserves all row data — no longer drops+recreates table
CI / test (20.x) (push) Successful in 10m2s
CI / test (22.x) (push) Successful in 10m0s
CI / test (18.x) (push) Successful in 10m8s
CI / test (24.x) (push) Successful in 9m56s

This commit is contained in:
thzxx
2026-07-29 22:07:22 +08:00
parent 6de6e97e19
commit e778d1feae
8 changed files with 39 additions and 16 deletions
+8 -3
View File
@@ -300,16 +300,21 @@ export class QueryExecutor {
if (schema.columns[stmt.column.name]) {
throw new DatabaseError(`Column "${stmt.column.name}" already exists in table "${stmt.name}"`, 'COLUMN_EXISTS');
}
// 直接在 schema 引用上添加列(已有行的该列值为 undefined/default
schema.columns[stmt.column.name] = astColumnToColumnDef(stmt.column);
} else if (stmt.action === 'DROP') {
if (!schema.columns[stmt.column.name]) {
throw new DatabaseError(`Column "${stmt.column.name}" does not exist in table "${stmt.name}"`, 'COLUMN_NOT_FOUND');
}
// 从 schema 引用上删除列定义(保留所有行数据)
delete schema.columns[stmt.column.name];
// 清除已有行中该列的值(MemoryEngine 的 find 返回引用,delete 直接生效)
const rows = await this.engine.find(stmt.name, { table: stmt.name });
const colName = stmt.column.name;
for (const row of rows) {
if (colName in row) delete row[colName];
}
}
// 重建表结构
await this.engine.dropTable(stmt.name);
await this.engine.createTable(schema);
}
private async executeTruncateTable(stmt: TruncateTableStatement): Promise<void> {