Fix CREATE INDEX with quoted identifiers

This commit is contained in:
Iaroslav Zeigerman
2025-09-25 08:55:29 -07:00
parent cc70ec892b
commit b34e53d6c6
4 changed files with 36 additions and 10 deletions

View File

@@ -42,6 +42,8 @@ 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);
let opts = crate::vdbe::builder::ProgramBuilderOpts {
@@ -66,6 +68,7 @@ pub fn translate_create_index(
let Some(tbl) = table.btree() else {
crate::bail_parse_error!("Error: table '{tbl_name}' is not a b-tree table.");
};
let original_columns = columns;
let columns = resolve_sorted_columns(&tbl, columns)?;
let idx = Arc::new(Index {
@@ -152,10 +155,10 @@ pub fn translate_create_index(
db: 0,
});
let sql = create_idx_stmt_to_sql(
&tbl_name,
&idx_name,
original_tbl_name,
original_idx_name,
unique_if_not_exists,
&columns,
original_columns,
&idx.where_clause.clone(),
);
let resolver = Resolver::new(schema, syms);
@@ -353,7 +356,7 @@ fn create_idx_stmt_to_sql(
tbl_name: &str,
idx_name: &str,
unique_if_not_exists: (bool, bool),
cols: &[((usize, &Column), SortOrder)],
cols: &[SortedColumn],
where_clause: &Option<Box<Expr>>,
) -> String {
let mut sql = String::with_capacity(128);
@@ -369,12 +372,19 @@ fn create_idx_stmt_to_sql(
sql.push_str(" ON ");
sql.push_str(tbl_name);
sql.push_str(" (");
for (i, (col, order)) in cols.iter().enumerate() {
for (i, col) in cols.iter().enumerate() {
if i > 0 {
sql.push_str(", ");
}
sql.push_str(col.1.name.as_ref().unwrap());
if *order == SortOrder::Desc {
let col_ident = match col.expr.as_ref() {
Expr::Id(ast::Name::Ident(col_name))
| Expr::Id(ast::Name::Quoted(col_name))
| Expr::Name(ast::Name::Ident(col_name))
| Expr::Name(ast::Name::Quoted(col_name)) => col_name,
_ => unreachable!("expressions in CREATE INDEX should have been rejected earlier"),
};
sql.push_str(col_ident);
if col.order.unwrap_or(SortOrder::Asc) == SortOrder::Desc {
sql.push_str(" DESC");
}
}

View File

@@ -911,7 +911,7 @@ impl<'a> Parser<'a> {
fn parse_fullname(&mut self, allow_alias: bool) -> Result<QualifiedName> {
let first_name = self.parse_nm()?;
let secone_name = if let Some(tok) = self.peek()? {
let second_name = if let Some(tok) = self.peek()? {
if tok.token_type == Some(TK_DOT) {
eat_assert!(self, TK_DOT);
Some(self.parse_nm()?)
@@ -937,10 +937,10 @@ impl<'a> Parser<'a> {
None
};
if let Some(secone_name) = secone_name {
if let Some(second_name) = second_name {
Ok(QualifiedName {
db_name: Some(first_name),
name: secone_name,
name: second_name,
alias: alias_name,
})
} else {

View File

@@ -35,6 +35,7 @@ source $testdir/boolean.test
source $testdir/literal.test
source $testdir/null.test
source $testdir/create_table.test
source $testdir/create_index.test
source $testdir/collate.test
source $testdir/values.test
source $testdir/integrity_check.test

15
testing/create_index.test Executable file
View File

@@ -0,0 +1,15 @@
#!/usr/bin/env tclsh
set testdir [file dirname $argv0]
source $testdir/tester.tcl
do_execsql_test_on_specific_db {:memory:} create-index-quoted-identifiers {
CREATE TABLE "t t" ("a a");
CREATE INDEX "idx idx" ON "t t" ("a a");
CREATE UNIQUE INDEX "unique idx idx" ON "t t" ("a a");
SELECT sql FROM sqlite_schema WHERE type='index';
} {
"CREATE INDEX \"idx idx\" ON \"t t\" (\"a a\")"
"CREATE UNIQUE INDEX \"unique idx idx\" ON \"t t\" (\"a a\")"
}