Merge 'Disallow multiple primary keys in table definition' from Jussi Saurio

Closes #3309

Reviewed-by: Pere Diaz Bou <pere-altea@homail.com>

Closes #3340
This commit is contained in:
Jussi Saurio
2025-09-26 09:16:14 +03:00
committed by GitHub
2 changed files with 33 additions and 20 deletions

View File

@@ -1041,6 +1041,12 @@ pub fn create_table(
..
} = &c.constraint
{
if !primary_key_columns.is_empty() {
crate::bail_parse_error!(
"table \"{}\" has more than one primary key",
tbl_name
);
}
if *auto_increment {
has_autoincrement = true;
}
@@ -1129,6 +1135,12 @@ pub fn create_table(
auto_increment,
..
} => {
if !primary_key_columns.is_empty() {
crate::bail_parse_error!(
"table \"{}\" has more than one primary key",
tbl_name
);
}
primary_key = true;
if auto_increment {
has_autoincrement = true;
@@ -1991,13 +2003,12 @@ mod tests {
}
#[test]
pub fn test_column_is_rowid_alias_inline_composite_primary_key() -> Result<()> {
pub fn test_multiple_pk_forbidden() -> Result<()> {
let sql = r#"CREATE TABLE t1 (a INTEGER PRIMARY KEY, b TEXT PRIMARY KEY);"#;
let table = BTreeTable::from_sql(sql, 0)?;
let column = table.get_column("a").unwrap().1;
let table = BTreeTable::from_sql(sql, 0);
let error = table.unwrap_err();
assert!(
!table.column_is_rowid_alias(column),
"column 'a´ shouldn't be a rowid alias because table has composite primary key"
matches!(error, LimboError::ParseError(e) if e.contains("table \"t1\" has more than one primary key"))
);
Ok(())
}
@@ -2033,22 +2044,12 @@ mod tests {
}
#[test]
pub fn test_primary_key_inline_multiple() -> Result<()> {
pub fn test_primary_key_inline_multiple_forbidden() -> Result<()> {
let sql = r#"CREATE TABLE t1 (a INTEGER PRIMARY KEY, b TEXT PRIMARY KEY, c REAL);"#;
let table = BTreeTable::from_sql(sql, 0)?;
let column = table.get_column("a").unwrap().1;
assert!(column.primary_key, "column 'a' should be a primary key");
let column = table.get_column("b").unwrap().1;
assert!(column.primary_key, "column 'b' shouldn be a primary key");
let column = table.get_column("c").unwrap().1;
assert!(!column.primary_key, "column 'c' shouldn't be a primary key");
assert_eq!(
vec![
("a".to_string(), SortOrder::Asc),
("b".to_string(), SortOrder::Asc)
],
table.primary_key_columns,
"primary key column names should be ['a', 'b']"
let table = BTreeTable::from_sql(sql, 0);
let error = table.unwrap_err();
assert!(
matches!(error, LimboError::ParseError(e) if e.contains("table \"t1\" has more than one primary key"))
);
Ok(())
}

View File

@@ -33,3 +33,15 @@ do_execsql_test_on_specific_db {:memory:} create_table_with_empty_string_name {
insert into '' values(9);
select * from '';
} {9}
do_execsql_test_in_memory_any_error create_table_multiple_column_primary_keys {
CREATE TABLE t(a primary key, b primary key);
}
do_execsql_test_in_memory_any_error create_table_column_and_table_primary_keys {
CREATE TABLE t(a primary key, b,c, primary key(b,c));
}
do_execsql_test_in_memory_any_error create_table_multiple_table_primary_keys {
CREATE TABLE t(a,b,c,d,primary key(a,b), primary key(c,d));
}