mirror of
https://github.com/aljazceru/turso.git
synced 2026-02-09 18:24:20 +01:00
Fix existing resolve_label() calls to work with new system
This commit is contained in:
@@ -159,8 +159,7 @@ fn epilogue(
|
||||
err_code: 0,
|
||||
description: String::new(),
|
||||
});
|
||||
|
||||
program.resolve_label(init_label, program.offset());
|
||||
program.preassign_label_to_next_insn(init_label);
|
||||
|
||||
match txn_mode {
|
||||
TransactionMode::Read => program.emit_insn(Insn::Transaction { write: false }),
|
||||
@@ -297,7 +296,7 @@ pub fn emit_query<'a>(
|
||||
condition_metadata,
|
||||
&t_ctx.resolver,
|
||||
)?;
|
||||
program.resolve_label(jump_target_when_true, program.offset());
|
||||
program.preassign_label_to_next_insn(jump_target_when_true);
|
||||
}
|
||||
|
||||
// Set up main query execution loop
|
||||
@@ -308,8 +307,7 @@ pub fn emit_query<'a>(
|
||||
|
||||
// Clean up and close the main execution loop
|
||||
close_loop(program, t_ctx, &plan.table_references)?;
|
||||
|
||||
program.resolve_label(after_main_loop_label, program.offset());
|
||||
program.preassign_label_to_next_insn(after_main_loop_label);
|
||||
|
||||
let mut order_by_necessary = plan.order_by.is_some() && !plan.contains_constant_false_condition;
|
||||
let order_by = plan.order_by.as_ref();
|
||||
@@ -379,8 +377,7 @@ fn emit_program_for_delete(
|
||||
|
||||
// Clean up and close the main execution loop
|
||||
close_loop(program, &mut t_ctx, &plan.table_references)?;
|
||||
|
||||
program.resolve_label(after_main_loop_label, program.offset());
|
||||
program.preassign_label_to_next_insn(after_main_loop_label);
|
||||
|
||||
// Finalize program
|
||||
epilogue(program, init_label, start_offset, TransactionMode::Write)?;
|
||||
@@ -516,8 +513,7 @@ fn emit_program_for_update(
|
||||
)?;
|
||||
emit_update_insns(&plan, &t_ctx, program)?;
|
||||
close_loop(program, &mut t_ctx, &plan.table_references)?;
|
||||
|
||||
program.resolve_label(after_main_loop_label, program.offset());
|
||||
program.preassign_label_to_next_insn(after_main_loop_label);
|
||||
|
||||
// Finalize program
|
||||
epilogue(program, init_label, start_offset, TransactionMode::Write)?;
|
||||
@@ -570,7 +566,7 @@ fn emit_update_insns(
|
||||
meta,
|
||||
&t_ctx.resolver,
|
||||
)?;
|
||||
program.resolve_label(jump_target, program.offset());
|
||||
program.preassign_label_to_next_insn(jump_target);
|
||||
}
|
||||
let beg = program.alloc_registers(
|
||||
table_ref.table.columns().len()
|
||||
|
||||
@@ -275,16 +275,18 @@ pub fn emit_group_by<'a>(
|
||||
"start new group if comparison is not equal",
|
||||
);
|
||||
// If we are at a new group, continue. If we are at the same group, jump to the aggregation step (i.e. accumulate more values into the aggregations)
|
||||
let label_jump_after_comparison = program.allocate_label();
|
||||
program.emit_insn(Insn::Jump {
|
||||
target_pc_lt: program.offset().add(1u32),
|
||||
target_pc_lt: label_jump_after_comparison,
|
||||
target_pc_eq: agg_step_label,
|
||||
target_pc_gt: program.offset().add(1u32),
|
||||
target_pc_gt: label_jump_after_comparison,
|
||||
});
|
||||
|
||||
program.add_comment(
|
||||
program.offset(),
|
||||
"check if ended group had data, and output if so",
|
||||
);
|
||||
program.resolve_label(label_jump_after_comparison, program.offset());
|
||||
program.emit_insn(Insn::Gosub {
|
||||
target_pc: label_subrtn_acc_output,
|
||||
return_reg: reg_subrtn_acc_output_return_offset,
|
||||
@@ -364,8 +366,7 @@ pub fn emit_group_by<'a>(
|
||||
cursor_id: sort_cursor,
|
||||
pc_if_next: label_grouping_loop_start,
|
||||
});
|
||||
|
||||
program.resolve_label(label_grouping_loop_end, program.offset());
|
||||
program.preassign_label_to_next_insn(label_grouping_loop_end);
|
||||
|
||||
program.add_comment(program.offset(), "emit row for final group");
|
||||
program.emit_insn(Insn::Gosub {
|
||||
@@ -505,8 +506,7 @@ pub fn emit_group_by<'a>(
|
||||
program.emit_insn(Insn::Return {
|
||||
return_reg: reg_subrtn_acc_clear_return_offset,
|
||||
});
|
||||
|
||||
program.resolve_label(label_group_by_end, program.offset());
|
||||
program.preassign_label_to_next_insn(label_group_by_end);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@@ -149,8 +149,7 @@ pub fn translate_create_index(
|
||||
cursor_id: table_cursor_id,
|
||||
pc_if_empty: loop_end_label,
|
||||
});
|
||||
|
||||
program.resolve_label(loop_start_label, program.offset());
|
||||
program.preassign_label_to_next_insn(loop_start_label);
|
||||
|
||||
// Loop start:
|
||||
// Collect index values into start_reg..rowid_reg
|
||||
@@ -185,7 +184,7 @@ pub fn translate_create_index(
|
||||
cursor_id: table_cursor_id,
|
||||
pc_if_next: loop_start_label,
|
||||
});
|
||||
program.resolve_label(loop_end_label, program.offset());
|
||||
program.preassign_label_to_next_insn(loop_end_label);
|
||||
|
||||
// Open the index btree we created for writing to insert the
|
||||
// newly sorted index records.
|
||||
@@ -202,7 +201,7 @@ pub fn translate_create_index(
|
||||
cursor_id: sorter_cursor_id,
|
||||
pc_if_empty: sorted_loop_end,
|
||||
});
|
||||
program.resolve_label(sorted_loop_start, program.offset());
|
||||
program.preassign_label_to_next_insn(sorted_loop_start);
|
||||
let sorted_record_reg = program.alloc_register();
|
||||
program.emit_insn(Insn::SorterData {
|
||||
pseudo_cursor: pseudo_cursor_id,
|
||||
@@ -226,7 +225,7 @@ pub fn translate_create_index(
|
||||
cursor_id: sorter_cursor_id,
|
||||
pc_if_next: sorted_loop_start,
|
||||
});
|
||||
program.resolve_label(sorted_loop_end, program.offset());
|
||||
program.preassign_label_to_next_insn(sorted_loop_end);
|
||||
|
||||
// End of the outer loop
|
||||
//
|
||||
@@ -248,7 +247,7 @@ pub fn translate_create_index(
|
||||
|
||||
// Epilogue:
|
||||
program.emit_halt();
|
||||
program.resolve_label(init_label, program.offset());
|
||||
program.preassign_label_to_next_insn(init_label);
|
||||
program.emit_transaction(true);
|
||||
program.emit_constant_insns();
|
||||
program.emit_goto(start_offset);
|
||||
|
||||
@@ -13,16 +13,15 @@ use crate::vdbe::insn::{IdxInsertFlags, RegisterOrLiteral};
|
||||
use crate::vdbe::BranchOffset;
|
||||
use crate::{
|
||||
schema::{Column, Schema},
|
||||
translate::expr::translate_expr,
|
||||
vdbe::{
|
||||
builder::{CursorType, ProgramBuilder},
|
||||
insn::Insn,
|
||||
},
|
||||
SymbolTable,
|
||||
};
|
||||
use crate::{Result, VirtualTable};
|
||||
use crate::{Result, SymbolTable, VirtualTable};
|
||||
|
||||
use super::emitter::Resolver;
|
||||
use super::expr::{translate_expr_no_constant_opt, NoConstantOptReason};
|
||||
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
pub fn translate_insert(
|
||||
@@ -144,12 +143,15 @@ pub fn translate_insert(
|
||||
if inserting_multiple_rows {
|
||||
let yield_reg = program.alloc_register();
|
||||
let jump_on_definition_label = program.allocate_label();
|
||||
let start_offset_label = program.allocate_label();
|
||||
program.emit_insn(Insn::InitCoroutine {
|
||||
yield_reg,
|
||||
jump_on_definition: jump_on_definition_label,
|
||||
start_offset: program.offset().add(1u32),
|
||||
start_offset: start_offset_label,
|
||||
});
|
||||
|
||||
program.resolve_label(start_offset_label, program.offset());
|
||||
|
||||
for value in values {
|
||||
populate_column_registers(
|
||||
&mut program,
|
||||
@@ -166,7 +168,7 @@ pub fn translate_insert(
|
||||
});
|
||||
}
|
||||
program.emit_insn(Insn::EndCoroutine { yield_reg });
|
||||
program.resolve_label(jump_on_definition_label, program.offset());
|
||||
program.preassign_label_to_next_insn(jump_on_definition_label);
|
||||
|
||||
program.emit_insn(Insn::OpenWrite {
|
||||
cursor_id,
|
||||
@@ -268,8 +270,7 @@ pub fn translate_insert(
|
||||
err_code: SQLITE_CONSTRAINT_PRIMARYKEY,
|
||||
description: format!("{}.{}", table_name.0, rowid_column_name),
|
||||
});
|
||||
|
||||
program.resolve_label(make_record_label, program.offset());
|
||||
program.preassign_label_to_next_insn(make_record_label);
|
||||
}
|
||||
|
||||
match table.btree() {
|
||||
@@ -354,8 +355,8 @@ pub fn translate_insert(
|
||||
err_code: 0,
|
||||
description: String::new(),
|
||||
});
|
||||
program.preassign_label_to_next_insn(init_label);
|
||||
|
||||
program.resolve_label(init_label, program.offset());
|
||||
program.emit_insn(Insn::Transaction { write: true });
|
||||
program.emit_constant_insns();
|
||||
program.emit_insn(Insn::Goto {
|
||||
@@ -557,18 +558,26 @@ fn populate_column_registers(
|
||||
} else {
|
||||
target_reg
|
||||
};
|
||||
translate_expr(
|
||||
translate_expr_no_constant_opt(
|
||||
program,
|
||||
None,
|
||||
value.get(value_index).expect("value index out of bounds"),
|
||||
reg,
|
||||
resolver,
|
||||
NoConstantOptReason::RegisterReuse,
|
||||
)?;
|
||||
if write_directly_to_rowid_reg {
|
||||
program.emit_insn(Insn::SoftNull { reg: target_reg });
|
||||
}
|
||||
} else if let Some(default_expr) = mapping.default_value {
|
||||
translate_expr(program, None, default_expr, target_reg, resolver)?;
|
||||
translate_expr_no_constant_opt(
|
||||
program,
|
||||
None,
|
||||
default_expr,
|
||||
target_reg,
|
||||
resolver,
|
||||
NoConstantOptReason::RegisterReuse,
|
||||
)?;
|
||||
} else {
|
||||
// Column was not specified as has no DEFAULT - use NULL if it is nullable, otherwise error
|
||||
// Rowid alias columns can be NULL because we will autogenerate a rowid in that case.
|
||||
@@ -618,7 +627,14 @@ fn translate_virtual_table_insert(
|
||||
|
||||
let value_registers_start = program.alloc_registers(values[0].len());
|
||||
for (i, expr) in values[0].iter().enumerate() {
|
||||
translate_expr(program, None, expr, value_registers_start + i, resolver)?;
|
||||
translate_expr_no_constant_opt(
|
||||
program,
|
||||
None,
|
||||
expr,
|
||||
value_registers_start + i,
|
||||
resolver,
|
||||
NoConstantOptReason::RegisterReuse,
|
||||
)?;
|
||||
}
|
||||
/* *
|
||||
* Inserts for virtual tables are done in a single step.
|
||||
@@ -672,12 +688,12 @@ fn translate_virtual_table_insert(
|
||||
});
|
||||
|
||||
let halt_label = program.allocate_label();
|
||||
program.resolve_label(halt_label, program.offset());
|
||||
program.emit_insn(Insn::Halt {
|
||||
err_code: 0,
|
||||
description: String::new(),
|
||||
});
|
||||
|
||||
program.resolve_label(halt_label, program.offset());
|
||||
program.resolve_label(init_label, program.offset());
|
||||
|
||||
program.emit_insn(Insn::Goto {
|
||||
|
||||
@@ -18,7 +18,10 @@ use crate::{
|
||||
use super::{
|
||||
aggregation::translate_aggregation_step,
|
||||
emitter::{OperationMode, TranslateCtx},
|
||||
expr::{translate_condition_expr, translate_expr, ConditionMetadata},
|
||||
expr::{
|
||||
translate_condition_expr, translate_expr, translate_expr_no_constant_opt,
|
||||
ConditionMetadata, NoConstantOptReason,
|
||||
},
|
||||
group_by::is_column_in_group_by,
|
||||
optimizer::Optimizable,
|
||||
order_by::{order_by_sorter_insert, sorter_insert},
|
||||
@@ -238,7 +241,7 @@ pub fn open_loop(
|
||||
jump_on_definition: BranchOffset::Offset(0),
|
||||
start_offset: coroutine_implementation_start,
|
||||
});
|
||||
program.resolve_label(loop_start, program.offset());
|
||||
program.preassign_label_to_next_insn(loop_start);
|
||||
// A subquery within the main loop of a parent query has no cursor, so instead of advancing the cursor,
|
||||
// it emits a Yield which jumps back to the main loop of the subquery itself to retrieve the next row.
|
||||
// When the subquery coroutine completes, this instruction jumps to the label at the top of the termination_label_stack,
|
||||
@@ -265,7 +268,7 @@ pub fn open_loop(
|
||||
condition_metadata,
|
||||
&t_ctx.resolver,
|
||||
)?;
|
||||
program.resolve_label(jump_target_when_true, program.offset());
|
||||
program.preassign_label_to_next_insn(jump_target_when_true);
|
||||
}
|
||||
}
|
||||
Operation::Scan { iter_dir, .. } => {
|
||||
@@ -284,6 +287,7 @@ pub fn open_loop(
|
||||
pc_if_empty: loop_end,
|
||||
});
|
||||
}
|
||||
program.preassign_label_to_next_insn(loop_start);
|
||||
} else if let Some(vtab) = table.virtual_table() {
|
||||
let (start_reg, count, maybe_idx_str, maybe_idx_int) = if vtab
|
||||
.kind
|
||||
@@ -391,8 +395,8 @@ pub fn open_loop(
|
||||
idx_num: maybe_idx_int.unwrap_or(0) as usize,
|
||||
pc_if_empty: loop_end,
|
||||
});
|
||||
program.preassign_label_to_next_insn(loop_start);
|
||||
}
|
||||
program.resolve_label(loop_start, program.offset());
|
||||
|
||||
if let Some(table_cursor_id) = table_cursor_id {
|
||||
if let Some(index_cursor_id) = index_cursor_id {
|
||||
@@ -419,7 +423,7 @@ pub fn open_loop(
|
||||
condition_metadata,
|
||||
&t_ctx.resolver,
|
||||
)?;
|
||||
program.resolve_label(jump_target_when_true, program.offset());
|
||||
program.preassign_label_to_next_insn(jump_target_when_true);
|
||||
}
|
||||
}
|
||||
Operation::Search(search) => {
|
||||
@@ -527,7 +531,7 @@ pub fn open_loop(
|
||||
condition_metadata,
|
||||
&t_ctx.resolver,
|
||||
)?;
|
||||
program.resolve_label(jump_target_when_true, program.offset());
|
||||
program.preassign_label_to_next_insn(jump_target_when_true);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -815,6 +819,7 @@ pub fn close_loop(
|
||||
program.emit_insn(Insn::Goto {
|
||||
target_pc: loop_labels.loop_start,
|
||||
});
|
||||
program.preassign_label_to_next_insn(loop_labels.loop_end);
|
||||
}
|
||||
Operation::Scan { iter_dir, .. } => {
|
||||
program.resolve_label(loop_labels.next, program.offset());
|
||||
@@ -844,6 +849,7 @@ pub fn close_loop(
|
||||
}
|
||||
other => unreachable!("Unsupported table reference type: {:?}", other),
|
||||
}
|
||||
program.preassign_label_to_next_insn(loop_labels.loop_end);
|
||||
}
|
||||
Operation::Search(search) => {
|
||||
program.resolve_label(loop_labels.next, program.offset());
|
||||
@@ -869,11 +875,10 @@ pub fn close_loop(
|
||||
});
|
||||
}
|
||||
}
|
||||
program.preassign_label_to_next_insn(loop_labels.loop_end);
|
||||
}
|
||||
}
|
||||
|
||||
program.resolve_label(loop_labels.loop_end, program.offset());
|
||||
|
||||
// Handle OUTER JOIN logic. The reason this comes after the "loop end" mark is that we may need to still jump back
|
||||
// and emit a row with NULLs for the right table, and then jump back to the next row of the left table.
|
||||
if let Some(join_info) = table.join_info.as_ref() {
|
||||
@@ -913,7 +918,7 @@ pub fn close_loop(
|
||||
program.emit_insn(Insn::Goto {
|
||||
target_pc: lj_meta.label_match_flag_set_true,
|
||||
});
|
||||
program.resolve_label(label_when_right_table_notnull, program.offset());
|
||||
program.preassign_label_to_next_insn(label_when_right_table_notnull);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -972,7 +977,14 @@ fn emit_seek(
|
||||
}
|
||||
} else {
|
||||
let expr = &seek_def.key[i].0;
|
||||
translate_expr(program, Some(tables), &expr, reg, &t_ctx.resolver)?;
|
||||
translate_expr_no_constant_opt(
|
||||
program,
|
||||
Some(tables),
|
||||
&expr,
|
||||
reg,
|
||||
&t_ctx.resolver,
|
||||
NoConstantOptReason::RegisterReuse,
|
||||
)?;
|
||||
// If the seek key column is not verifiably non-NULL, we need check whether it is NULL,
|
||||
// and if so, jump to the loop end.
|
||||
// This is to avoid returning rows for e.g. SELECT * FROM t WHERE t.x > NULL,
|
||||
@@ -1046,7 +1058,7 @@ fn emit_seek_termination(
|
||||
is_index: bool,
|
||||
) -> Result<()> {
|
||||
let Some(termination) = seek_def.termination.as_ref() else {
|
||||
program.resolve_label(loop_start, program.offset());
|
||||
program.preassign_label_to_next_insn(loop_start);
|
||||
return Ok(());
|
||||
};
|
||||
|
||||
@@ -1081,16 +1093,17 @@ fn emit_seek_termination(
|
||||
// if the seek key is shorter than the termination key, we need to translate the remaining suffix of the termination key.
|
||||
// if not, we just reuse what was emitted for the seek.
|
||||
} else if seek_len < termination.len {
|
||||
translate_expr(
|
||||
translate_expr_no_constant_opt(
|
||||
program,
|
||||
Some(tables),
|
||||
&seek_def.key[i].0,
|
||||
reg,
|
||||
&t_ctx.resolver,
|
||||
NoConstantOptReason::RegisterReuse,
|
||||
)?;
|
||||
}
|
||||
}
|
||||
program.resolve_label(loop_start, program.offset());
|
||||
program.preassign_label_to_next_insn(loop_start);
|
||||
let mut rowid_reg = None;
|
||||
if !is_index {
|
||||
rowid_reg = Some(program.alloc_register());
|
||||
@@ -1177,11 +1190,12 @@ fn emit_autoindex(
|
||||
cursor_id: index_cursor_id,
|
||||
});
|
||||
// Rewind source table
|
||||
let label_ephemeral_build_loop_start = program.allocate_label();
|
||||
program.emit_insn(Insn::Rewind {
|
||||
cursor_id: table_cursor_id,
|
||||
pc_if_empty: label_ephemeral_build_end,
|
||||
pc_if_empty: label_ephemeral_build_loop_start,
|
||||
});
|
||||
let offset_ephemeral_build_loop_start = program.offset();
|
||||
program.preassign_label_to_next_insn(label_ephemeral_build_loop_start);
|
||||
// Emit all columns from source table that are needed in the ephemeral index.
|
||||
// Also reserve a register for the rowid if the source table has rowids.
|
||||
let num_regs_to_reserve = index.columns.len() + table_has_rowid as usize;
|
||||
@@ -1215,8 +1229,8 @@ fn emit_autoindex(
|
||||
});
|
||||
program.emit_insn(Insn::Next {
|
||||
cursor_id: table_cursor_id,
|
||||
pc_if_next: offset_ephemeral_build_loop_start,
|
||||
pc_if_next: label_ephemeral_build_loop_start,
|
||||
});
|
||||
program.resolve_label(label_ephemeral_build_end, program.offset());
|
||||
program.preassign_label_to_next_insn(label_ephemeral_build_end);
|
||||
Ok(index_cursor_id)
|
||||
}
|
||||
|
||||
@@ -124,8 +124,8 @@ pub fn emit_order_by(
|
||||
cursor_id: sort_cursor,
|
||||
pc_if_empty: sort_loop_end_label,
|
||||
});
|
||||
program.preassign_label_to_next_insn(sort_loop_start_label);
|
||||
|
||||
program.resolve_label(sort_loop_start_label, program.offset());
|
||||
emit_offset(program, t_ctx, plan, sort_loop_next_label)?;
|
||||
|
||||
program.emit_insn(Insn::SorterData {
|
||||
@@ -154,8 +154,7 @@ pub fn emit_order_by(
|
||||
cursor_id: sort_cursor,
|
||||
pc_if_next: sort_loop_start_label,
|
||||
});
|
||||
|
||||
program.resolve_label(sort_loop_end_label, program.offset());
|
||||
program.preassign_label_to_next_insn(sort_loop_end_label);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@@ -29,7 +29,7 @@ fn list_pragmas(
|
||||
}
|
||||
|
||||
program.emit_halt();
|
||||
program.resolve_label(init_label, program.offset());
|
||||
program.preassign_label_to_next_insn(init_label);
|
||||
program.emit_constant_insns();
|
||||
program.emit_goto(start_offset);
|
||||
}
|
||||
@@ -104,7 +104,7 @@ pub fn translate_pragma(
|
||||
},
|
||||
};
|
||||
program.emit_halt();
|
||||
program.resolve_label(init_label, program.offset());
|
||||
program.preassign_label_to_next_insn(init_label);
|
||||
program.emit_transaction(write);
|
||||
program.emit_constant_insns();
|
||||
program.emit_goto(start_offset);
|
||||
|
||||
@@ -37,7 +37,7 @@ pub fn translate_create_table(
|
||||
let init_label = program.emit_init();
|
||||
let start_offset = program.offset();
|
||||
program.emit_halt();
|
||||
program.resolve_label(init_label, program.offset());
|
||||
program.preassign_label_to_next_insn(init_label);
|
||||
program.emit_transaction(true);
|
||||
program.emit_constant_insns();
|
||||
program.emit_goto(start_offset);
|
||||
@@ -148,7 +148,7 @@ pub fn translate_create_table(
|
||||
|
||||
// TODO: SqlExec
|
||||
program.emit_halt();
|
||||
program.resolve_label(init_label, program.offset());
|
||||
program.preassign_label_to_next_insn(init_label);
|
||||
program.emit_transaction(true);
|
||||
program.emit_constant_insns();
|
||||
program.emit_goto(start_offset);
|
||||
@@ -448,7 +448,7 @@ pub fn translate_create_virtual_table(
|
||||
});
|
||||
let init_label = program.emit_init();
|
||||
program.emit_halt();
|
||||
program.resolve_label(init_label, program.offset());
|
||||
program.preassign_label_to_next_insn(init_label);
|
||||
program.emit_transaction(true);
|
||||
program.emit_constant_insns();
|
||||
return Ok(program);
|
||||
@@ -519,7 +519,7 @@ pub fn translate_create_virtual_table(
|
||||
});
|
||||
|
||||
program.emit_halt();
|
||||
program.resolve_label(init_label, program.offset());
|
||||
program.preassign_label_to_next_insn(init_label);
|
||||
program.emit_transaction(true);
|
||||
program.emit_constant_insns();
|
||||
program.emit_goto(start_offset);
|
||||
@@ -545,7 +545,7 @@ pub fn translate_drop_table(
|
||||
let init_label = program.emit_init();
|
||||
let start_offset = program.offset();
|
||||
program.emit_halt();
|
||||
program.resolve_label(init_label, program.offset());
|
||||
program.preassign_label_to_next_insn(init_label);
|
||||
program.emit_transaction(true);
|
||||
program.emit_constant_insns();
|
||||
program.emit_goto(start_offset);
|
||||
@@ -583,14 +583,14 @@ pub fn translate_drop_table(
|
||||
// 1. Remove all entries from the schema table related to the table we are dropping, except for triggers
|
||||
// loop to beginning of schema table
|
||||
let end_metadata_label = program.allocate_label();
|
||||
let metadata_loop = program.allocate_label();
|
||||
program.emit_insn(Insn::Rewind {
|
||||
cursor_id: sqlite_schema_cursor_id,
|
||||
pc_if_empty: end_metadata_label,
|
||||
});
|
||||
program.preassign_label_to_next_insn(metadata_loop);
|
||||
|
||||
// start loop on schema table
|
||||
let metadata_loop = program.allocate_label();
|
||||
program.resolve_label(metadata_loop, program.offset());
|
||||
program.emit_insn(Insn::Column {
|
||||
cursor_id: sqlite_schema_cursor_id,
|
||||
column: 2,
|
||||
@@ -627,7 +627,7 @@ pub fn translate_drop_table(
|
||||
cursor_id: sqlite_schema_cursor_id,
|
||||
pc_if_next: metadata_loop,
|
||||
});
|
||||
program.resolve_label(end_metadata_label, program.offset());
|
||||
program.preassign_label_to_next_insn(end_metadata_label);
|
||||
// end of loop on schema table
|
||||
|
||||
// 2. Destroy the indices within a loop
|
||||
@@ -696,7 +696,7 @@ pub fn translate_drop_table(
|
||||
|
||||
// end of the program
|
||||
program.emit_halt();
|
||||
program.resolve_label(init_label, program.offset());
|
||||
program.preassign_label_to_next_insn(init_label);
|
||||
program.emit_transaction(true);
|
||||
program.emit_constant_insns();
|
||||
|
||||
|
||||
@@ -52,7 +52,7 @@ pub fn emit_subquery<'a>(
|
||||
t_ctx: &mut TranslateCtx<'a>,
|
||||
) -> Result<usize> {
|
||||
let yield_reg = program.alloc_register();
|
||||
let coroutine_implementation_start_offset = program.offset().add(1u32);
|
||||
let coroutine_implementation_start_offset = program.allocate_label();
|
||||
match &mut plan.query_type {
|
||||
SelectQueryType::Subquery {
|
||||
yield_reg: y,
|
||||
@@ -91,6 +91,7 @@ pub fn emit_subquery<'a>(
|
||||
jump_on_definition: subquery_body_end_label,
|
||||
start_offset: coroutine_implementation_start_offset,
|
||||
});
|
||||
program.preassign_label_to_next_insn(coroutine_implementation_start_offset);
|
||||
// Normally we mark each LIMIT value as a constant insn that is emitted only once, but in the case of a subquery,
|
||||
// we need to initialize it every time the subquery is run; otherwise subsequent runs of the subquery will already
|
||||
// have the LIMIT counter at 0, and will never return rows.
|
||||
@@ -103,6 +104,6 @@ pub fn emit_subquery<'a>(
|
||||
let result_column_start_reg = emit_query(program, plan, &mut metadata)?;
|
||||
program.resolve_label(end_coroutine_label, program.offset());
|
||||
program.emit_insn(Insn::EndCoroutine { yield_reg });
|
||||
program.resolve_label(subquery_body_end_label, program.offset());
|
||||
program.preassign_label_to_next_insn(subquery_body_end_label);
|
||||
Ok(result_column_start_reg)
|
||||
}
|
||||
|
||||
@@ -33,7 +33,7 @@ pub fn translate_tx_begin(
|
||||
}
|
||||
}
|
||||
program.emit_halt();
|
||||
program.resolve_label(init_label, program.offset());
|
||||
program.preassign_label_to_next_insn(init_label);
|
||||
program.emit_goto(start_offset);
|
||||
Ok(program)
|
||||
}
|
||||
@@ -52,7 +52,7 @@ pub fn translate_tx_commit(_tx_name: Option<Name>) -> Result<ProgramBuilder> {
|
||||
rollback: false,
|
||||
});
|
||||
program.emit_halt();
|
||||
program.resolve_label(init_label, program.offset());
|
||||
program.preassign_label_to_next_insn(init_label);
|
||||
program.emit_goto(start_offset);
|
||||
Ok(program)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user