{"record":{"id":"9b3992d966f8a96f","repo":"databendlabs/databend","slug":"invalid-temp-table-desc","errorCode":null,"errorMessage":"Invalid temp table desc: {}","messagePattern":"Invalid temp table desc: (.+?)","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/query/storages/common/session/src/transaction.rs","lineNumber":100,"sourceCode":"    // TODO doc this\n    table_tnx_begin_timestamps: HashMap<u64, DateTime<Utc>>,\n\n    temp_table_desc_to_id: HashMap<String, u64>,\n    mutated_temp_tables: HashMap<u64, TempTable>,\n}\n\n#[derive(Debug, Clone)]\npub struct StreamSnapshot {\n    pub stream: TableInfo,\n    pub source: TableInfo,\n    pub max_batch_size: Option<u64>,\n}\n\nimpl TxnBuffer {\n    fn parse_db_tbl_name(desc: &str) -> (String, String) {\n        let (db_raw, table_raw) = desc\n            .split_once('.')\n            .unwrap_or_else(|| panic!(\"Invalid temp table desc: {}\", desc));\n        let db_name = db_raw[1..db_raw.len() - 1].to_string();\n        let table_name = table_raw[1..table_raw.len() - 1].to_string();\n        (db_name, table_name)\n    }\n\n    fn clear(&mut self) {\n        std::mem::take(self);\n    }\n\n    fn update_multi_table_meta(\n        &mut self,\n        tenant: &Tenant,\n        mut req: UpdateMultiTableMetaReq,\n    ) -> Result<()> {\n        // Bind the transaction to the first non-conflicting tenant that updates meta.\n        // Later updates must stay on the same tenant; commit uses this bound value.\n        match &self.tenant {\n            None => self.tenant = Some(tenant.clone()),","sourceCodeStart":82,"sourceCodeEnd":118,"githubUrl":"https://github.com/databendlabs/databend/blob/288d84d76e20a2f8f7173bda9691eb6ece301aa9/src/query/storages/common/session/src/transaction.rs#L82-L118","documentation":"Temp table descriptors are encoded as `\"<db_name>.<table_name>\"` where each name part is wrapped in quotes, e.g. `\"db\".\"tbl\"`. `TxnBuffer::parse_db_tbl_name` panics when the descriptor contains no `.` separator, meaning the desc string is malformed or was produced by a different code path/version.","triggerScenarios":"Calling any `TxnBuffer` operation (append/commit/clear paths) with a temp-table desc that lacks a dot, e.g. a bare table name `mytable` instead of `\"mydb\".\"mytable\"`, or an empty desc string.","commonSituations":"Hand-crafted or externally supplied temp table descriptors, version skew between nodes writing descs in an older format, or corruption of serialized transaction buffers containing temp table entries.","solutions":["Inspect the malformed desc value and fix the producer so it emits the quoted `\"db\".\"table\"` format.","Add a validation step before registering temp tables so unquoted or dot-less names are rejected at the API boundary with a proper error instead of a panic.","Check for version skew: if the desc came from persisted state written by an older release, migrate or re-create the affected temp tables."],"exampleFix":"// before: silent panic on malformed desc\nlet (db_raw, table_raw) = desc.split_once('.')\n    .unwrap_or_else(|| panic!(\"Invalid temp table desc: {}\", desc));\n// after: return a typed error\nlet (db_raw, table_raw) = desc.split_once('.')\n    .ok_or_else(|| ErrorCode::BadArguments(format!(\"Invalid temp table desc: {desc}\")))?;","handlingStrategy":"validation","validationCode":"// Validate the temp table desc before handing it to TxnBuffer\nfn is_valid_temp_table_desc(desc: &str) -> bool {\n    let parts: Vec<&str> = desc.split('.').collect();\n    parts.len() == 2 && parts[0].len() >= 2 && parts[1].len() >= 2\n}","typeGuard":null,"tryCatchPattern":"// Catch panics from parsing untrusted descs in batch processing\nlet result = std::panic::catch_unwind(|| txn_buffer.parse_and_apply(desc));\nmatch result {\n    Ok(res) => res?,\n    Err(_) => return Err(format!(\"Invalid temp table desc: {desc}\")),\n}","preventionTips":["Always build temp table descs via the quoting helper (quoted db and table joined by a dot).","Reject unquoted or dot-less table names at the API boundary.","Never feed externally supplied strings directly as temp table descriptors.","Add a round-trip unit test: format desc, parse it back, compare."],"tags":["rust","panic","parsing","temp-table","transaction-buffer"],"backgroundTag":"invalid-argument-format","analyzedSha":"288d84d76e20a2f8f7173bda9691eb6ece301aa9","analyzedAt":"2026-09-11T11:29:36.208Z","contentChangedAt":"2026-09-11T11:29:36.208Z","schemaVersion":2},"datasetVersion":"2026-09-16T04:17:20.429Z"}