diff --git a/core/translate/expr.rs b/core/translate/expr.rs index c1a279bfd..434c71cf0 100644 --- a/core/translate/expr.rs +++ b/core/translate/expr.rs @@ -3475,6 +3475,7 @@ pub fn bind_and_rewrite_expr<'a>( } } Expr::Qualified(tbl, id) => { + tracing::debug!("bind_and_rewrite_expr({:?}, {:?})", tbl, id); let normalized_table_name = normalize_ident(tbl.as_str()); let matching_tbl = referenced_tables .find_table_and_internal_id_by_identifier(&normalized_table_name); @@ -3504,6 +3505,7 @@ pub fn bind_and_rewrite_expr<'a>( column: col_idx, is_rowid_alias: col.is_rowid_alias, }; + tracing::debug!("rewritten to column"); referenced_tables.mark_column_used(tbl_id, col_idx); return Ok(WalkControl::Continue); } @@ -4147,7 +4149,7 @@ fn determine_column_alias( ) -> Option { // First check for explicit alias if let Some(As::As(name)) = explicit_alias { - return Some(name.to_string()); + return Some(name.as_str().to_string()); } // For ROWID expressions, use "rowid" as the alias diff --git a/core/translate/index.rs b/core/translate/index.rs index 0fe25b882..ff895ba23 100644 --- a/core/translate/index.rs +++ b/core/translate/index.rs @@ -21,15 +21,15 @@ use crate::{ insn::{IdxInsertFlags, Insn, RegisterOrLiteral}, }, }; -use turso_parser::ast::{Expr, SortOrder, SortedColumn}; +use turso_parser::ast::{Expr, Name, SortOrder, SortedColumn}; use super::schema::{emit_schema_entry, SchemaEntryType, SQLITE_TABLEID}; #[allow(clippy::too_many_arguments)] pub fn translate_create_index( unique_if_not_exists: (bool, bool), - idx_name: &str, - tbl_name: &str, + idx_name: &Name, + tbl_name: &Name, columns: &[SortedColumn], schema: &Schema, syms: &SymbolTable, @@ -37,6 +37,11 @@ pub fn translate_create_index( connection: &Arc, where_clause: Option>, ) -> crate::Result { + let original_idx_name = idx_name; + let original_tbl_name = tbl_name; + let idx_name = normalize_ident(idx_name.as_str()); + let tbl_name = normalize_ident(tbl_name.as_str()); + if tbl_name.eq_ignore_ascii_case("sqlite_sequence") { crate::bail_parse_error!("table sqlite_sequence may not be indexed"); } @@ -45,10 +50,6 @@ pub fn translate_create_index( "CREATE INDEX is disabled by default. Run with `--experimental-indexes` to enable this feature." ); } - let original_idx_name = idx_name; - let original_tbl_name = tbl_name; - let idx_name = normalize_ident(idx_name); - let tbl_name = normalize_ident(tbl_name); if RESERVED_TABLE_PREFIXES .iter() .any(|prefix| idx_name.starts_with(prefix)) @@ -173,8 +174,8 @@ pub fn translate_create_index( db: 0, }); let sql = create_idx_stmt_to_sql( - original_tbl_name, - original_idx_name, + &original_tbl_name.as_ident(), + &original_idx_name.as_ident(), unique_if_not_exists, original_columns, &idx.where_clause.clone(), @@ -392,10 +393,10 @@ fn create_idx_stmt_to_sql( sql.push_str(", "); } let col_ident = match col.expr.as_ref() { - Expr::Id(name) | Expr::Name(name) => name.as_str(), + Expr::Id(name) | Expr::Name(name) => name.as_ident(), _ => unreachable!("expressions in CREATE INDEX should have been rejected earlier"), }; - sql.push_str(col_ident); + sql.push_str(&col_ident); if col.order.unwrap_or(SortOrder::Asc) == SortOrder::Desc { sql.push_str(" DESC"); } diff --git a/core/translate/mod.rs b/core/translate/mod.rs index 2263e3a97..fdeb39ae9 100644 --- a/core/translate/mod.rs +++ b/core/translate/mod.rs @@ -165,8 +165,8 @@ pub fn translate_inner( where_clause, } => translate_create_index( (unique, if_not_exists), - idx_name.name.as_str(), - tbl_name.as_str(), + &idx_name.name, + &tbl_name, &columns, schema, syms, @@ -197,7 +197,7 @@ pub fn translate_inner( .. } => view::translate_create_view( schema, - view_name.name.as_str(), + &view_name.name, &select, &columns, connection.clone(), @@ -208,7 +208,7 @@ pub fn translate_inner( view_name, select, .. } => view::translate_create_materialized_view( schema, - view_name.name.as_str(), + &view_name.name, &select, connection.clone(), syms, diff --git a/core/translate/schema.rs b/core/translate/schema.rs index f2da72cd8..54699cacc 100644 --- a/core/translate/schema.rs +++ b/core/translate/schema.rs @@ -463,15 +463,15 @@ fn create_vtable_body_to_str(vtab: &ast::CreateVirtualTable, module: Arc, syms: &SymbolTable, @@ -25,7 +25,7 @@ pub fn translate_create_materialized_view( )); } - let normalized_view_name = normalize_ident(view_name); + let normalized_view_name = normalize_ident(view_name.as_str()); // Check if view already exists if schema @@ -46,7 +46,7 @@ pub fn translate_create_materialized_view( let view_columns = view_column_schema.flat_columns(); // Reconstruct the SQL string for storage - let sql = create_materialized_view_to_str(view_name, select_stmt); + let sql = create_materialized_view_to_str(&view_name.as_ident(), select_stmt); // Create a btree for storing the materialized view state // This btree will hold the materialized rows (row_id -> values) @@ -145,14 +145,16 @@ pub fn translate_create_materialized_view( // Add the DBSP state table to sqlite_master (required for materialized views) // Include the version number in the table name use crate::incremental::compiler::DBSP_CIRCUIT_VERSION; - let dbsp_table_name = - format!("{DBSP_TABLE_PREFIX}{DBSP_CIRCUIT_VERSION}_{normalized_view_name}"); + let dbsp_table_name = ast::Name::exact(format!( + "{DBSP_TABLE_PREFIX}{DBSP_CIRCUIT_VERSION}_{normalized_view_name}" + )); + let dbsp_table_ident = dbsp_table_name.as_ident(); // The element_id column uses SQLite's dynamic typing system to store different value types: // - For hash-based operators (joins, filters): stores INTEGER hash values or rowids // - For future MIN/MAX operators: stores the actual values being compared (INTEGER, REAL, TEXT, BLOB) // SQLite's type affinity and sorting rules ensure correct ordering within each operator's data let dbsp_sql = format!( - "CREATE TABLE {dbsp_table_name} (\ + "CREATE TABLE {dbsp_table_ident} (\ operator_id INTEGER NOT NULL, \ zset_id BLOB NOT NULL, \ element_id BLOB NOT NULL, \ @@ -168,8 +170,8 @@ pub fn translate_create_materialized_view( sqlite_schema_cursor_id, None, // cdc_table_cursor_id SchemaEntryType::Table, - &dbsp_table_name, - &dbsp_table_name, + dbsp_table_name.as_str(), + dbsp_table_name.as_str(), dbsp_state_root_reg, // Root for DBSP state table Some(dbsp_sql), )?; @@ -186,7 +188,8 @@ pub fn translate_create_materialized_view( // Register the index in sqlite_schema let dbsp_index_name = format!( "{}{}_1", - PRIMARY_KEY_AUTOMATIC_INDEX_NAME_PREFIX, &dbsp_table_name + PRIMARY_KEY_AUTOMATIC_INDEX_NAME_PREFIX, + &dbsp_table_name.as_str() ); emit_schema_entry( &mut program, @@ -195,7 +198,7 @@ pub fn translate_create_materialized_view( None, // cdc_table_cursor_id SchemaEntryType::Index, &dbsp_index_name, - &dbsp_table_name, + dbsp_table_name.as_str(), dbsp_index_root_reg, None, // Automatic indexes don't store SQL )?; @@ -231,14 +234,14 @@ fn create_materialized_view_to_str(view_name: &str, select_stmt: &ast::Select) - pub fn translate_create_view( schema: &Schema, - view_name: &str, + view_name: &ast::Name, select_stmt: &ast::Select, _columns: &[ast::IndexedColumn], _connection: Arc, syms: &SymbolTable, mut program: ProgramBuilder, ) -> Result { - let normalized_view_name = normalize_ident(view_name); + let normalized_view_name = normalize_ident(view_name.as_str()); // Check if view already exists if schema.get_view(&normalized_view_name).is_some() @@ -252,7 +255,7 @@ pub fn translate_create_view( } // Reconstruct the SQL string - let sql = create_view_to_str(view_name, select_stmt); + let sql = create_view_to_str(&view_name.as_ident(), select_stmt); // Open cursor to sqlite_schema table let table = schema.get_btree_table(SQLITE_TABLEID).unwrap();