{"record":{"id":"c6b10bdcb193a00e","repo":"tursodatabase/turso","slug":"insn-column-on-virtual-table-cursor-use-insn-vcol","errorCode":null,"errorMessage":"Insn:Column on virtual table cursor, use Insn:VColumn instead","messagePattern":"Insn:Column on virtual table cursor, use Insn:VColumn instead","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"core/vdbe/execute.rs","lineNumber":2314,"sourceCode":"                state.registers[dest].set_null();\n            }\n        }\n        CursorType::Pseudo(_) => {\n            let content_reg = crate::get_cursor!(state, cursor_id)\n                .as_pseudo_mut()\n                .content_reg();\n            return op_column_fetch_pseudo(state, content_reg, column, dest);\n        }\n        CursorType::IndexMethod(..) => {\n            let cursor = state.cursors[cursor_id]\n                .as_mut()\n                .expect(\"cursor should exist\");\n            let cursor = cursor.as_index_method_mut();\n            let value = return_if_io!(state, cursor.query_column(column));\n            state.registers[dest].set_value(value);\n        }\n        CursorType::VirtualTable(_) => {\n            panic!(\"Insn:Column on virtual table cursor, use Insn:VColumn instead\");\n        }\n    }\n    Ok(InsnFunctionStepResult::Step)\n}\n\nfn apply_column_default(default: &Option<Value>, reg: &mut Register) -> Result<()> {\n    let Some(default) = default else {\n        reg.set_null();\n        return Ok(());\n    };\n    match (default, reg) {\n        (Value::Text(new_text), Register::Value(Value::Text(existing_text))) => {\n            existing_text.do_extend(new_text)?;\n        }\n        (Value::Blob(new_blob), Register::Value(Value::Blob(existing_blob))) => {\n            existing_blob.do_extend(new_blob)?;\n        }\n        (default, reg) => {","sourceCodeStart":2296,"sourceCodeEnd":2332,"githubUrl":"https://github.com/tursodatabase/turso/blob/492c4a71cd7c2649e7df83da1471b74f4b1c7aa9/core/vdbe/execute.rs#L2296-L2332","documentation":"Insn::Column executed on a CursorType::VirtualTable cursor. Virtual table columns must be read with Insn::VColumn, which invokes the module's column callback; generic Column decodes a B-tree record and cannot work on a module cursor. The translator emitted the generic opcode against a virtual table — a codegen bug for that statement shape.","triggerScenarios":"SELECT lists, RETURNING clauses, or trigger/view bodies over virtual tables in code paths that build column reads generically — e.g. RETURNING on vtab DML, or views/triggers layered over vtab modules like csv, fts, or pragma-backed tables.","commonSituations":"Extensions and catalog-style vtabs combined with RETURNING, views, or triggers; engine versions where column emission was unified.","solutions":["Report with the module and SQL — translation must emit VColumn for vtab cursors","Remove RETURNING or wrap access so the vtab is read through a plain SELECT list","Query the vtab directly instead of through the layered view/trigger","Upgrade"],"exampleFix":"// contributor fix in translate/ column emission: branch on the cursor kind\nif matches!(cursor_type, CursorType::VirtualTable(_)) {\n    program.emit_insn(Insn::VColumn { cursor_id, column, dest_reg });\n} else {\n    program.emit_insn(Insn::Column { cursor_id, column, dest_reg });\n}","handlingStrategy":"validation","validationCode":"// generic Column must not read virtual table cursors\nfor insn in &program.insns {\n    if let Insn::Column { cursor_id, .. } = insn {\n        if matches!(program.cursor_ref.get(*cursor_id).map(|(_, t)| t), Some(CursorType::VirtualTable(_))) {\n            crate::bail_parse_error!(\"Column on virtual table cursor; VColumn required\");\n        }\n    }\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Add RETURNING/views/triggers over vtabs to the extension test matrix","Debug-build audit pairing Column vs VColumn with cursor kinds","Validate vtab statements against sqlite3 first"],"tags":["vdbe","executor","virtual-table","column","codegen","panic","runtime"],"backgroundTag":"virtual-table-instruction-mismatch","analyzedSha":"492c4a71cd7c2649e7df83da1471b74f4b1c7aa9","analyzedAt":"2026-08-20T07:02:18.389Z","contentChangedAt":"2026-08-20T07:02:18.389Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}