mirror of
https://github.com/aljazceru/turso.git
synced 2026-02-01 06:14:23 +01:00
Disallow joining more than 63 tables
Returns an error instead of panicing
This commit is contained in:
@@ -187,6 +187,12 @@ fn optimize_table_access(
|
||||
order_by: &mut Vec<(Box<ast::Expr>, SortOrder)>,
|
||||
group_by: &mut Option<GroupBy>,
|
||||
) -> Result<Option<Vec<JoinOrderMember>>> {
|
||||
if table_references.joined_tables().len() > TableReferences::MAX_JOINED_TABLES {
|
||||
crate::bail_parse_error!(
|
||||
"Only up to {} tables can be joined",
|
||||
TableReferences::MAX_JOINED_TABLES
|
||||
);
|
||||
}
|
||||
let access_methods_arena = RefCell::new(Vec::new());
|
||||
let maybe_order_target = compute_order_target(order_by, group_by.as_mut());
|
||||
let constraints_per_table =
|
||||
|
||||
@@ -583,6 +583,11 @@ pub struct TableReferences {
|
||||
}
|
||||
|
||||
impl TableReferences {
|
||||
/// The maximum number of tables that can be joined together in a query.
|
||||
/// This limit is arbitrary, although we currently use a u128 to represent the [crate::translate::planner::TableMask],
|
||||
/// which can represent up to 128 tables.
|
||||
/// Even at 63 tables we currently cannot handle the optimization performantly, hence the arbitrary cap.
|
||||
pub const MAX_JOINED_TABLES: usize = 63;
|
||||
pub fn new(
|
||||
joined_tables: Vec<JoinedTable>,
|
||||
outer_query_refs: Vec<OuterQueryReference>,
|
||||
|
||||
@@ -897,3 +897,26 @@ fn test_multiple_connections_visibility() -> anyhow::Result<()> {
|
||||
assert_eq!(rows, vec![vec![rusqlite::types::Value::Integer(2)]]);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
/// Test that we can only join up to 63 tables, and trying to join more should fail with an error instead of panicing.
|
||||
fn test_max_joined_tables_limit() {
|
||||
let tmp_db = TempDatabase::new("test_max_joined_tables_limit", false);
|
||||
let conn = tmp_db.connect_limbo();
|
||||
|
||||
// Create 64 tables
|
||||
for i in 0..64 {
|
||||
conn.execute(&format!("CREATE TABLE t{} (id INTEGER)", i)).unwrap();
|
||||
}
|
||||
|
||||
// Try to join 64 tables - should fail
|
||||
let mut sql = String::from("SELECT * FROM t0");
|
||||
for i in 1..64 {
|
||||
sql.push_str(&format!(" JOIN t{} ON t{}.id = t0.id", i, i));
|
||||
}
|
||||
|
||||
let Err(LimboError::ParseError(result)) = conn.prepare(&sql) else {
|
||||
panic!("Expected an error but got no error");
|
||||
};
|
||||
assert!(result.contains("Only up to 63 tables can be joined"));
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user