Skip to content

Commit 00f90ea

Browse files
committed
fix
1 parent f578082 commit 00f90ea

2 files changed

Lines changed: 36 additions & 50 deletions

File tree

src/meta/api/src/api_impl/schema_api.rs

Lines changed: 8 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,6 @@ use chrono::DateTime;
2121
use chrono::Utc;
2222
use databend_common_meta_app::app_error::AppError;
2323
use databend_common_meta_app::app_error::DropTableWithDropTime;
24-
use databend_common_meta_app::app_error::TableEngineMismatch;
2524
use databend_common_meta_app::app_error::UndropTableAlreadyExists;
2625
use databend_common_meta_app::app_error::UndropTableHasNoHistory;
2726
use databend_common_meta_app::app_error::UndropTableRetentionGuard;
@@ -178,16 +177,21 @@ pub async fn construct_drop_table_txn_operations(
178177
tenant: &Tenant,
179178
catalog_name: Option<String>,
180179
table_id: u64,
181-
expected_engine: Option<&str>,
180+
preloaded_table_meta: Option<SeqV<TableMeta>>,
182181
db_id: u64,
183182
if_exists: bool,
184183
if_delete: bool,
185184
txn: &mut TxnRequest,
186185
) -> Result<(u64, u64), KVAppError> {
187186
let tbid = TableId { table_id };
188187

189-
// Check if table exists.
190-
let (tb_meta_seq, tb_meta) = kv_api.get_pb_seq_and_value(&tbid).await?;
188+
// Reuse metadata already loaded by CREATE OR REPLACE; ordinary DROP callers
189+
// do not have it and load it here. A preloaded value must belong to `table_id`.
190+
let (tb_meta_seq, tb_meta) = if let Some(preloaded_table_meta) = preloaded_table_meta {
191+
(preloaded_table_meta.seq, Some(preloaded_table_meta.data))
192+
} else {
193+
kv_api.get_pb_seq_and_value(&tbid).await?
194+
};
191195
if tb_meta_seq == 0 {
192196
return Err(KVAppError::AppError(AppError::UnknownTableId(
193197
UnknownTableId::new(table_id, "drop_table_by_id failed to find valid tb_meta"),
@@ -235,16 +239,6 @@ pub async fn construct_drop_table_txn_operations(
235239
);
236240

237241
let mut tb_meta = tb_meta.unwrap();
238-
// CREATE OR REPLACE passes `expected_engine` to prevent replacing an existing
239-
// table with a different engine. Reject the mismatch before this helper marks
240-
// the existing table as dropped; ordinary DROP operations pass `None`.
241-
if let Some(expected_engine) = expected_engine {
242-
if !tb_meta.engine.eq_ignore_ascii_case(expected_engine) {
243-
return Err(KVAppError::AppError(
244-
TableEngineMismatch::new(table_name, &tb_meta.engine, expected_engine).into(),
245-
));
246-
}
247-
}
248242
// drop a table with drop_on time
249243
if tb_meta.drop_on.is_some() {
250244
return if if_exists {

src/meta/api/src/api_impl/table_api.rs

Lines changed: 28 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -362,55 +362,47 @@ where
362362
});
363363
}
364364
CreateOption::CreateOrReplace => {
365-
if req.as_dropped {
366-
// CREATE OR REPLACE must not replace an existing table with a
367-
// different engine. Atomic CTAS keeps the existing table visible
368-
// while the insert pipeline runs, so it cannot use the drop helper
369-
// that normally enforces this rule. Validate the engine here;
370-
// `commit_table_meta()` publishes the replacement after the insert
371-
// succeeds.
372-
let existing_meta =
373-
self.get_pb(&TableId::new(*id.data)).await?.ok_or_else(|| {
374-
KVAppError::AppError(AppError::UnknownTableId(
375-
UnknownTableId::new(
376-
*id.data,
377-
"create or replace failed to find existing table meta",
378-
),
379-
))
380-
})?;
381-
if !existing_meta
382-
.engine
383-
.eq_ignore_ascii_case(&req.table_meta.engine)
384-
{
385-
return Err(KVAppError::AppError(
386-
TableEngineMismatch::new(
387-
req.table_name(),
388-
&existing_meta.engine,
389-
&req.table_meta.engine,
390-
)
391-
.into(),
392-
));
393-
}
365+
// CREATE OR REPLACE must not replace an existing table with a
366+
// different engine.
367+
let existing_table_meta = self
368+
.get_pb(&TableId::new(*id.data))
369+
.await?
370+
.ok_or_else(|| {
371+
KVAppError::AppError(AppError::UnknownTableId(UnknownTableId::new(
372+
*id.data,
373+
"create or replace failed to find existing table meta",
374+
)))
375+
})?;
376+
if !existing_table_meta
377+
.engine
378+
.eq_ignore_ascii_case(&req.table_meta.engine)
379+
{
380+
return Err(KVAppError::AppError(
381+
TableEngineMismatch::new(
382+
req.table_name(),
383+
&existing_table_meta.engine,
384+
&req.table_meta.engine,
385+
)
386+
.into(),
387+
));
388+
}
394389

390+
if req.as_dropped {
395391
// No TableMeta seq condition is needed: the engine is immutable
396392
// for a table id, and the `key_dbid_tbname` condition below ensures
397393
// that the name still refers to this table id.
398394

399-
// If the table is being created as a dropped table, we do not
400-
// need to combine with drop_table_txn operations, just return
401-
// the sequence number associated with the value part of
402-
// the key-value pair (key_dbid_tbname, table_id).
403395
SeqV::new(id.seq, *id.data)
404396
} else {
405-
// The drop helper rejects a mismatched engine before it
406-
// marks the existing table as dropped.
397+
// Reuse the metadata loaded for the engine check when marking the
398+
// existing table as dropped.
407399
let (seq, id) = construct_drop_table_txn_operations(
408400
self,
409401
req.name_ident.table_name.clone(),
410402
&req.name_ident.tenant,
411403
req.catalog_name.clone(),
412404
*id.data,
413-
Some(&req.table_meta.engine),
405+
Some(existing_table_meta),
414406
*seq_db_id.data,
415407
true,
416408
false,

0 commit comments

Comments
 (0)