Skip to content

Commit 04b7ecb

Browse files
committed
Add multi-table integration tests
1 parent 56d8bec commit 04b7ecb

1 file changed

Lines changed: 205 additions & 0 deletions

File tree

src/app.rs

Lines changed: 205 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1347,6 +1347,211 @@ mod tests {
13471347
);
13481348
}
13491349

1350+
// ==================== Multi-table Integration Tests ====================
1351+
1352+
#[test]
1353+
fn test_multi_table_cross_join() {
1354+
let dir = tempdir().unwrap();
1355+
1356+
// Create file for table "a"
1357+
let file_path_a = dir.path().join("a.jsonl");
1358+
let mut file_a = File::create(file_path_a.clone()).unwrap();
1359+
writeln!(file_a, r#"{{"x": 1}}"#).unwrap();
1360+
writeln!(file_a, r#"{{"x": 2}}"#).unwrap();
1361+
file_a.sync_all().unwrap();
1362+
drop(file_a);
1363+
1364+
// Create file for table "b"
1365+
let file_path_b = dir.path().join("b.jsonl");
1366+
let mut file_b = File::create(file_path_b.clone()).unwrap();
1367+
writeln!(file_b, r#"{{"y": 10}}"#).unwrap();
1368+
writeln!(file_b, r#"{{"y": 20}}"#).unwrap();
1369+
file_b.sync_all().unwrap();
1370+
drop(file_b);
1371+
1372+
let mut data_sources = common::types::DataSourceRegistry::new();
1373+
data_sources.insert("a".to_string(), common::types::DataSource::File(file_path_a, "jsonl".to_string(), "a".to_string()));
1374+
data_sources.insert("b".to_string(), common::types::DataSource::File(file_path_b, "jsonl".to_string(), "b".to_string()));
1375+
1376+
let result = run(r#"SELECT a.x, b.y FROM a CROSS JOIN b"#, data_sources, OutputMode::Csv);
1377+
assert_eq!(result, Ok(()));
1378+
1379+
dir.close().unwrap();
1380+
}
1381+
1382+
#[test]
1383+
fn test_multi_table_left_join() {
1384+
let dir = tempdir().unwrap();
1385+
1386+
// Create file for table "a"
1387+
let file_path_a = dir.path().join("a.jsonl");
1388+
let mut file_a = File::create(file_path_a.clone()).unwrap();
1389+
writeln!(file_a, r#"{{"id": 1, "x": "hello"}}"#).unwrap();
1390+
writeln!(file_a, r#"{{"id": 2, "x": "world"}}"#).unwrap();
1391+
writeln!(file_a, r#"{{"id": 3, "x": "foo"}}"#).unwrap();
1392+
file_a.sync_all().unwrap();
1393+
drop(file_a);
1394+
1395+
// Create file for table "b"
1396+
let file_path_b = dir.path().join("b.jsonl");
1397+
let mut file_b = File::create(file_path_b.clone()).unwrap();
1398+
writeln!(file_b, r#"{{"id": 1, "y": "alpha"}}"#).unwrap();
1399+
writeln!(file_b, r#"{{"id": 3, "y": "beta"}}"#).unwrap();
1400+
file_b.sync_all().unwrap();
1401+
drop(file_b);
1402+
1403+
let mut data_sources = common::types::DataSourceRegistry::new();
1404+
data_sources.insert("a".to_string(), common::types::DataSource::File(file_path_a, "jsonl".to_string(), "a".to_string()));
1405+
data_sources.insert("b".to_string(), common::types::DataSource::File(file_path_b, "jsonl".to_string(), "b".to_string()));
1406+
1407+
let result = run(r#"SELECT a.x, b.y FROM a LEFT JOIN b ON a.id = b.id"#, data_sources, OutputMode::Csv);
1408+
assert_eq!(result, Ok(()));
1409+
1410+
dir.close().unwrap();
1411+
}
1412+
1413+
#[test]
1414+
fn test_multi_table_comma_join() {
1415+
let dir = tempdir().unwrap();
1416+
1417+
// Create file for table "a"
1418+
let file_path_a = dir.path().join("a.jsonl");
1419+
let mut file_a = File::create(file_path_a.clone()).unwrap();
1420+
writeln!(file_a, r#"{{"x": 1}}"#).unwrap();
1421+
writeln!(file_a, r#"{{"x": 2}}"#).unwrap();
1422+
file_a.sync_all().unwrap();
1423+
drop(file_a);
1424+
1425+
// Create file for table "b"
1426+
let file_path_b = dir.path().join("b.jsonl");
1427+
let mut file_b = File::create(file_path_b.clone()).unwrap();
1428+
writeln!(file_b, r#"{{"y": 10}}"#).unwrap();
1429+
writeln!(file_b, r#"{{"y": 20}}"#).unwrap();
1430+
file_b.sync_all().unwrap();
1431+
drop(file_b);
1432+
1433+
let mut data_sources = common::types::DataSourceRegistry::new();
1434+
data_sources.insert("a".to_string(), common::types::DataSource::File(file_path_a, "jsonl".to_string(), "a".to_string()));
1435+
data_sources.insert("b".to_string(), common::types::DataSource::File(file_path_b, "jsonl".to_string(), "b".to_string()));
1436+
1437+
let result = run(r#"SELECT a.x, b.y FROM a, b"#, data_sources, OutputMode::Csv);
1438+
assert_eq!(result, Ok(()));
1439+
1440+
dir.close().unwrap();
1441+
}
1442+
1443+
#[test]
1444+
fn test_multi_table_unknown_table_error() {
1445+
let dir = tempdir().unwrap();
1446+
1447+
let file_path_a = dir.path().join("a.jsonl");
1448+
let mut file_a = File::create(file_path_a.clone()).unwrap();
1449+
writeln!(file_a, r#"{{"x": 1}}"#).unwrap();
1450+
file_a.sync_all().unwrap();
1451+
drop(file_a);
1452+
1453+
let mut data_sources = common::types::DataSourceRegistry::new();
1454+
data_sources.insert("a".to_string(), common::types::DataSource::File(file_path_a, "jsonl".to_string(), "a".to_string()));
1455+
1456+
let result = run(r#"SELECT * FROM unknown_table"#, data_sources, OutputMode::Csv);
1457+
assert!(result.is_err(), "Expected error for unknown table, got Ok");
1458+
1459+
dir.close().unwrap();
1460+
}
1461+
1462+
#[test]
1463+
fn test_multi_table_backward_compat() {
1464+
let dir = tempdir().unwrap();
1465+
1466+
let file_path = dir.path().join("compat.jsonl");
1467+
let mut file = File::create(file_path.clone()).unwrap();
1468+
writeln!(file, r#"{{"x": 1}}"#).unwrap();
1469+
writeln!(file, r#"{{"x": 2}}"#).unwrap();
1470+
file.sync_all().unwrap();
1471+
drop(file);
1472+
1473+
let data_source = common::types::DataSource::File(file_path, "jsonl".to_string(), "it".to_string());
1474+
let data_sources: common::types::DataSourceRegistry = vec![("it".to_string(), data_source)].into_iter().collect();
1475+
1476+
let result = run(r#"SELECT * FROM it LIMIT 1"#, data_sources, OutputMode::Csv);
1477+
assert_eq!(result, Ok(()));
1478+
1479+
dir.close().unwrap();
1480+
}
1481+
1482+
#[test]
1483+
fn test_multi_table_stdin_in_join_right_side_error() {
1484+
let dir = tempdir().unwrap();
1485+
1486+
let file_path_a = dir.path().join("a.jsonl");
1487+
let mut file_a = File::create(file_path_a.clone()).unwrap();
1488+
writeln!(file_a, r#"{{"x": 1}}"#).unwrap();
1489+
file_a.sync_all().unwrap();
1490+
drop(file_a);
1491+
1492+
let mut data_sources = common::types::DataSourceRegistry::new();
1493+
data_sources.insert("a".to_string(), common::types::DataSource::File(file_path_a, "jsonl".to_string(), "a".to_string()));
1494+
data_sources.insert("b".to_string(), common::types::DataSource::Stdin("jsonl".to_string(), "b".to_string()));
1495+
1496+
// "b" is stdin and used as the right side of a join — should produce an error
1497+
let result = run(r#"SELECT a.x, b.y FROM a CROSS JOIN b"#, data_sources, OutputMode::Csv);
1498+
assert!(result.is_err(), "Expected error when stdin is on the right side of a join");
1499+
1500+
dir.close().unwrap();
1501+
}
1502+
1503+
#[test]
1504+
fn test_multi_table_with_where_filter() {
1505+
let dir = tempdir().unwrap();
1506+
1507+
// Create file for table "a"
1508+
let file_path_a = dir.path().join("a.jsonl");
1509+
let mut file_a = File::create(file_path_a.clone()).unwrap();
1510+
writeln!(file_a, r#"{{"x": 1}}"#).unwrap();
1511+
writeln!(file_a, r#"{{"x": 2}}"#).unwrap();
1512+
writeln!(file_a, r#"{{"x": 3}}"#).unwrap();
1513+
file_a.sync_all().unwrap();
1514+
drop(file_a);
1515+
1516+
// Create file for table "b"
1517+
let file_path_b = dir.path().join("b.jsonl");
1518+
let mut file_b = File::create(file_path_b.clone()).unwrap();
1519+
writeln!(file_b, r#"{{"y": 2}}"#).unwrap();
1520+
writeln!(file_b, r#"{{"y": 3}}"#).unwrap();
1521+
writeln!(file_b, r#"{{"y": 4}}"#).unwrap();
1522+
file_b.sync_all().unwrap();
1523+
drop(file_b);
1524+
1525+
let mut data_sources = common::types::DataSourceRegistry::new();
1526+
data_sources.insert("a".to_string(), common::types::DataSource::File(file_path_a, "jsonl".to_string(), "a".to_string()));
1527+
data_sources.insert("b".to_string(), common::types::DataSource::File(file_path_b, "jsonl".to_string(), "b".to_string()));
1528+
1529+
let result = run(r#"SELECT a.x, b.y FROM a, b WHERE a.x = b.y"#, data_sources, OutputMode::Csv);
1530+
assert_eq!(result, Ok(()));
1531+
1532+
dir.close().unwrap();
1533+
}
1534+
1535+
#[test]
1536+
fn test_multi_table_case_sensitive_name_error() {
1537+
let dir = tempdir().unwrap();
1538+
1539+
let file_path = dir.path().join("mytable.jsonl");
1540+
let mut file = File::create(file_path.clone()).unwrap();
1541+
writeln!(file, r#"{{"x": 1}}"#).unwrap();
1542+
file.sync_all().unwrap();
1543+
drop(file);
1544+
1545+
let mut data_sources = common::types::DataSourceRegistry::new();
1546+
data_sources.insert("MyTable".to_string(), common::types::DataSource::File(file_path, "jsonl".to_string(), "MyTable".to_string()));
1547+
1548+
// Query uses lowercase "mytable" but registry has "MyTable" — should fail
1549+
let result = run(r#"SELECT * FROM mytable"#, data_sources, OutputMode::Csv);
1550+
assert!(result.is_err(), "Expected error for case-sensitive table name mismatch");
1551+
1552+
dir.close().unwrap();
1553+
}
1554+
13501555
#[test]
13511556
fn test_squid_count_by_status() {
13521557
let lines = &[

0 commit comments

Comments
 (0)