From b5f2f375b8d7fb27dfb9004f8f0a05caabc75ff9 Mon Sep 17 00:00:00 2001 From: Pere Diaz Bou Date: Mon, 16 Jun 2025 17:42:08 +0200 Subject: [PATCH] disable alter, delete, create index, insert and update for indexes --- core/translate/alter.rs | 9 +++++++++ core/translate/delete.rs | 9 +++++++++ core/translate/index.rs | 7 +++++++ core/translate/insert.rs | 10 +++++++++- core/translate/schema.rs | 3 +++ core/translate/update.rs | 8 ++++++++ 6 files changed, 45 insertions(+), 1 deletion(-) diff --git a/core/translate/alter.rs b/core/translate/alter.rs index 39d158127..62649a90e 100644 --- a/core/translate/alter.rs +++ b/core/translate/alter.rs @@ -2,6 +2,7 @@ use fallible_iterator::FallibleIterator as _; use limbo_sqlite3_parser::{ast, lexer::sql::Parser}; use crate::{ + bail_parse_error, function::{AlterTableFunc, Func}, schema::{Column, Schema}, util::normalize_ident, @@ -24,6 +25,14 @@ pub fn translate_alter_table( ) -> Result { let (table_name, alter_table) = alter; let ast::Name(table_name) = table_name.name; + let indexes = schema.get_indices(&table_name); + if !indexes.is_empty() && cfg!(not(feature = "index_experimental")) { + // Let's disable altering a table with indices altogether instead of checking column by + // column to be extra safe. + bail_parse_error!( + "Alter table disabled for table with indexes without index_experimental feature flag" + ); + } let Some(original_btree) = schema .get_table(&table_name) diff --git a/core/translate/delete.rs b/core/translate/delete.rs index 1ddf25ece..3fe7af06e 100644 --- a/core/translate/delete.rs +++ b/core/translate/delete.rs @@ -1,3 +1,4 @@ +use crate::bail_parse_error; use crate::schema::Table; use crate::translate::emitter::emit_program; use crate::translate::optimizer::optimize_plan; @@ -18,6 +19,14 @@ pub fn translate_delete( syms: &SymbolTable, mut program: ProgramBuilder, ) -> Result { + let indexes = schema.get_indices(&tbl_name.name.to_string()); + if !indexes.is_empty() && cfg!(not(feature = "index_experimental")) { + // Let's disable altering a table with indices altogether instead of checking column by + // column to be extra safe. + bail_parse_error!( + "DELETE into table disabled for table with indexes and without index_experimental feature flag" + ); + } let mut delete_plan = prepare_delete_plan( schema, tbl_name, diff --git a/core/translate/index.rs b/core/translate/index.rs index a645582f2..ffb623a8f 100644 --- a/core/translate/index.rs +++ b/core/translate/index.rs @@ -1,5 +1,6 @@ use std::sync::Arc; +use crate::bail_parse_error; use crate::vdbe::insn::CmpInsFlags; use crate::{ schema::{BTreeTable, Column, Index, IndexColumn, PseudoTable, Schema}, @@ -23,6 +24,9 @@ pub fn translate_create_index( schema: &Schema, mut program: ProgramBuilder, ) -> crate::Result { + if cfg!(not(feature = "index_experimental")) { + bail_parse_error!("CREATE INDEX enabled only with index_experimental feature"); + } let idx_name = normalize_ident(idx_name); let tbl_name = normalize_ident(tbl_name); let opts = crate::vdbe::builder::ProgramBuilderOpts { @@ -296,6 +300,9 @@ pub fn translate_drop_index( schema: &Schema, mut program: ProgramBuilder, ) -> crate::Result { + if cfg!(not(feature = "index_experimental")) { + bail_parse_error!("DROP INDEX enabled only with index_experimental feature"); + } let idx_name = normalize_ident(idx_name); let opts = crate::vdbe::builder::ProgramBuilderOpts { query_mode: mode, diff --git a/core/translate/insert.rs b/core/translate/insert.rs index 342ef6b50..e9bcbd4d2 100644 --- a/core/translate/insert.rs +++ b/core/translate/insert.rs @@ -10,6 +10,7 @@ use crate::util::normalize_ident; use crate::vdbe::builder::{ProgramBuilderOpts, QueryMode}; use crate::vdbe::insn::{IdxInsertFlags, InsertFlags, RegisterOrLiteral}; use crate::vdbe::BranchOffset; +use crate::{bail_parse_error, Result, SymbolTable, VirtualTable}; use crate::{ schema::{Column, Schema}, vdbe::{ @@ -17,7 +18,6 @@ use crate::{ insn::Insn, }, }; -use crate::{Result, SymbolTable, VirtualTable}; use super::emitter::Resolver; use super::expr::{translate_expr, translate_expr_no_constant_opt, NoConstantOptReason}; @@ -58,6 +58,14 @@ pub fn translate_insert( crate::bail_parse_error!("ON CONFLICT clause is not supported"); } + let indexes = schema.get_indices(&tbl_name.name.to_string()); + if !indexes.is_empty() && cfg!(not(feature = "index_experimental")) { + // Let's disable altering a table with indices altogether instead of checking column by + // column to be extra safe. + bail_parse_error!( + "INSERT table disabled for table with indexes and without index_experimental feature flag" + ); + } let table_name = &tbl_name.name; let table = match schema.get_table(table_name.0.as_str()) { Some(table) => table, diff --git a/core/translate/schema.rs b/core/translate/schema.rs index 7b0bfe907..e4d5f5948 100644 --- a/core/translate/schema.rs +++ b/core/translate/schema.rs @@ -93,6 +93,9 @@ pub fn translate_create_table( let index_regs = check_automatic_pk_index_required(&body, &mut program, &tbl_name.name.0)?; if let Some(index_regs) = index_regs.as_ref() { + if cfg!(not(feature = "index_experimental")) { + bail_parse_error!("Constraints UNIQUE and PRIMARY KEY (unless INTEGER PRIMARY KEY) on table are not supported without indexes"); + } for index_reg in index_regs.clone() { program.emit_insn(Insn::CreateBtree { db: 0, diff --git a/core/translate/update.rs b/core/translate/update.rs index d4af63b0e..7cb94d6f3 100644 --- a/core/translate/update.rs +++ b/core/translate/update.rs @@ -101,6 +101,14 @@ pub fn prepare_update_plan( bail_parse_error!("ON CONFLICT clause is not supported"); } let table_name = &body.tbl_name.name; + let indexes = schema.get_indices(&table_name.to_string()); + if !indexes.is_empty() && cfg!(not(feature = "index_experimental")) { + // Let's disable altering a table with indices altogether instead of checking column by + // column to be extra safe. + bail_parse_error!( + "INSERT table disabled for table with indexes and without index_experimental feature flag" + ); + } let table = match schema.get_table(table_name.0.as_str()) { Some(table) => table, None => bail_parse_error!("Parse error: no such table: {}", table_name),