Merge 'BTreeTable::to_sql: wrap special column names in brackets' from Nils Koch

Closes #2055

Reviewed-by: Jussi Saurio <jussi.saurio@gmail.com>

Closes #2126
This commit is contained in:
Jussi Saurio
2025-07-21 00:22:49 +03:00
2 changed files with 45 additions and 1 deletions

View File

@@ -435,7 +435,16 @@ impl BTreeTable {
if i > 0 {
sql.push_str(", ");
}
sql.push_str(column.name.as_ref().expect("column name is None"));
// we need to wrap the column name in square brackets if it contains special characters
let column_name = column.name.as_ref().expect("column name is None");
if identifier_contains_special_chars(column_name) {
sql.push('[');
sql.push_str(column_name);
sql.push(']');
} else {
sql.push_str(column_name);
}
if !column.ty_str.is_empty() {
sql.push(' ');
@@ -464,6 +473,10 @@ impl BTreeTable {
}
}
fn identifier_contains_special_chars(name: &str) -> bool {
name.chars().any(|c| !c.is_ascii_alphanumeric() && c != '_')
}
#[derive(Debug, Default, Clone, Copy)]
pub struct PseudoCursorType {
pub column_count: usize,
@@ -1650,6 +1663,25 @@ mod tests {
assert_eq!(expected, actual);
}
#[test]
pub fn test_special_column_names() -> Result<()> {
let tests = [
("foobar", "CREATE TABLE t (foobar TEXT)"),
("_table_name3", "CREATE TABLE t (_table_name3 TEXT)"),
("special name", "CREATE TABLE t ([special name] TEXT)"),
("foo&bar", "CREATE TABLE t ([foo&bar] TEXT)"),
(" name", "CREATE TABLE t ([ name] TEXT)"),
];
for (input_column_name, expected_sql) in tests {
let sql = format!("CREATE TABLE t ([{input_column_name}] TEXT)");
let actual = BTreeTable::from_sql(&sql, 0)?.to_sql();
assert_eq!(expected_sql, actual);
}
Ok(())
}
#[test]
#[should_panic]
fn test_automatic_index_single_column() {

View File

@@ -95,6 +95,18 @@ do_execsql_test_on_specific_db {:memory:} alter-table-drop-column {
"3"
}
do_execsql_test_on_specific_db {:memory:} alter-table-drop-column-special-name {
CREATE TABLE t(a, b, [c c]);
INSERT INTO t VALUES (1, 2, 3);
ALTER TABLE t DROP COLUMN b;
SELECT "c c" FROM t;
SELECT sql FROM sqlite_schema;
} {
3
"CREATE TABLE t (a, [c c])"
}
do_execsql_test_in_memory_any_error fail-alter-table-drop-unique-column {
CREATE TABLE t(a, b UNIQUE);
ALTER TABLE t DROP b;