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
+9 -3
View File
@@ -5660,17 +5660,23 @@ class QueryExecutor {
if (schema.columns[stmt.column.name]) { if (schema.columns[stmt.column.name]) {
throw new DatabaseError(`Column "${stmt.column.name}" already exists in table "${stmt.name}"`, 'COLUMN_EXISTS'); 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); schema.columns[stmt.column.name] = astColumnToColumnDef(stmt.column);
} }
else if (stmt.action === 'DROP') { else if (stmt.action === 'DROP') {
if (!schema.columns[stmt.column.name]) { if (!schema.columns[stmt.column.name]) {
throw new DatabaseError(`Column "${stmt.column.name}" does not exist in table "${stmt.name}"`, 'COLUMN_NOT_FOUND'); throw new DatabaseError(`Column "${stmt.column.name}" does not exist in table "${stmt.name}"`, 'COLUMN_NOT_FOUND');
} }
// 从 schema 引用上删除列定义(保留所有行数据)
delete schema.columns[stmt.column.name]; 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);
} }
async executeTruncateTable(stmt) { async executeTruncateTable(stmt) {
const exists = await this.engine.hasTable(stmt.name); const exists = await this.engine.hasTable(stmt.name);
+1 -1
View File
File diff suppressed because one or more lines are too long
+9 -3
View File
@@ -5656,17 +5656,23 @@ class QueryExecutor {
if (schema.columns[stmt.column.name]) { if (schema.columns[stmt.column.name]) {
throw new DatabaseError(`Column "${stmt.column.name}" already exists in table "${stmt.name}"`, 'COLUMN_EXISTS'); 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); schema.columns[stmt.column.name] = astColumnToColumnDef(stmt.column);
} }
else if (stmt.action === 'DROP') { else if (stmt.action === 'DROP') {
if (!schema.columns[stmt.column.name]) { if (!schema.columns[stmt.column.name]) {
throw new DatabaseError(`Column "${stmt.column.name}" does not exist in table "${stmt.name}"`, 'COLUMN_NOT_FOUND'); throw new DatabaseError(`Column "${stmt.column.name}" does not exist in table "${stmt.name}"`, 'COLUMN_NOT_FOUND');
} }
// 从 schema 引用上删除列定义(保留所有行数据)
delete schema.columns[stmt.column.name]; 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);
} }
async executeTruncateTable(stmt) { async executeTruncateTable(stmt) {
const exists = await this.engine.hasTable(stmt.name); const exists = await this.engine.hasTable(stmt.name);
+1 -1
View File
File diff suppressed because one or more lines are too long
+9 -3
View File
@@ -5662,17 +5662,23 @@
if (schema.columns[stmt.column.name]) { if (schema.columns[stmt.column.name]) {
throw new DatabaseError(`Column "${stmt.column.name}" already exists in table "${stmt.name}"`, 'COLUMN_EXISTS'); 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); schema.columns[stmt.column.name] = astColumnToColumnDef(stmt.column);
} }
else if (stmt.action === 'DROP') { else if (stmt.action === 'DROP') {
if (!schema.columns[stmt.column.name]) { if (!schema.columns[stmt.column.name]) {
throw new DatabaseError(`Column "${stmt.column.name}" does not exist in table "${stmt.name}"`, 'COLUMN_NOT_FOUND'); throw new DatabaseError(`Column "${stmt.column.name}" does not exist in table "${stmt.name}"`, 'COLUMN_NOT_FOUND');
} }
// 从 schema 引用上删除列定义(保留所有行数据)
delete schema.columns[stmt.column.name]; 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);
} }
async executeTruncateTable(stmt) { async executeTruncateTable(stmt) {
const exists = await this.engine.hasTable(stmt.name); const exists = await this.engine.hasTable(stmt.name);
+1 -1
View File
File diff suppressed because one or more lines are too long
+1 -1
View File
File diff suppressed because one or more lines are too long
+8 -3
View File
@@ -300,16 +300,21 @@ export class QueryExecutor {
if (schema.columns[stmt.column.name]) { if (schema.columns[stmt.column.name]) {
throw new DatabaseError(`Column "${stmt.column.name}" already exists in table "${stmt.name}"`, 'COLUMN_EXISTS'); 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); schema.columns[stmt.column.name] = astColumnToColumnDef(stmt.column);
} else if (stmt.action === 'DROP') { } else if (stmt.action === 'DROP') {
if (!schema.columns[stmt.column.name]) { if (!schema.columns[stmt.column.name]) {
throw new DatabaseError(`Column "${stmt.column.name}" does not exist in table "${stmt.name}"`, 'COLUMN_NOT_FOUND'); throw new DatabaseError(`Column "${stmt.column.name}" does not exist in table "${stmt.name}"`, 'COLUMN_NOT_FOUND');
} }
// 从 schema 引用上删除列定义(保留所有行数据)
delete schema.columns[stmt.column.name]; 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> { private async executeTruncateTable(stmt: TruncateTableStatement): Promise<void> {