#![cfg(feature = "std")]
use remdb::*;
use serial_test::serial;
mod common;
use crate::common::platform::TEST_PLATFORM;
use common::{setup_test_db, setup_test_db_with_memory};
remdb::table!(
TEST_TABLE,
10, primary_key: id,
secondary_index: name,
fields: {
id: i32,
name: str(32),
age: i8,
active: bool,
created_at: u64
}
);
remdb::table!(
ORDERS_TABLE,
10, primary_key: id,
secondary_index: user_id,
fields: {
id: i32,
user_id: i32,
product: str(32),
amount: i32
}
);
remdb::database!(
TEST_DB,
tables: [TEST_TABLE, ORDERS_TABLE],
total_memory: 1048576 );
#[test]
#[serial]
fn test_sql_query() {
setup_test_db();
let config = &TEST_DB;
let db = unsafe { init_global_db(config).unwrap() };
println!("=== 测试各种SQL语法 ===");
let valid_queries = [
"SELECT * FROM TEST_TABLE",
"SELECT name, age FROM TEST_TABLE",
"SELECT * FROM TEST_TABLE WHERE id = 1",
"SELECT * FROM TEST_TABLE WHERE age > 25 AND active = true",
"SELECT * FROM TEST_TABLE ORDER BY name ASC",
"SELECT * FROM TEST_TABLE ORDER BY age DESC",
"SELECT * FROM TEST_TABLE LIMIT 5",
"SELECT * FROM TEST_TABLE WHERE active = false LIMIT 2",
];
for query in valid_queries {
let result = db.sql_query(query);
assert!(result.is_ok(), "查询 '{}' 应该成功执行", query);
}
let invalid_queries = [
"SELECT * FROM", "SELECT * FROM WHERE id = 1", "SELECT * FROM TEST_TABLE WHERE", "SELECT * FROM TEST_TABLE ORDER BY", "SELECT * FROM TEST_TABLE LIMIT", ];
for query in invalid_queries {
let result = db.sql_query(query);
assert!(result.is_err(), "查询 '{}' 应该失败", query);
}
println!("=== 插入测试数据和查询 ===");
#[repr(C)]
struct TestRecord {
id: i32, name: [u8; 32], age: i8, active: u8, _padding: [u8; 2], created_at: u64, }
let test_data = [
(1, "Alice", 25, true, 1620000000000),
(2, "Bob", 30, true, 1620000001000),
(3, "Charlie", 35, false, 1620000002000),
(4, "David", 22, true, 1620000003000),
(5, "Eve", 28, false, 1620000004000),
];
for (id, name, age, active, created_at) in test_data {
let mut record = TestRecord {
id,
name: [0u8; 32],
age,
active: if active { 1 } else { 0 }, _padding: [0u8; 2], created_at,
};
let name_bytes = name.as_bytes();
record.name[..name_bytes.len()].copy_from_slice(name_bytes);
let insert_id = unsafe {
db.get_table_mut(0)
.unwrap()
.insert(&record as *const _ as *const u8)
.unwrap()
};
assert!(insert_id < config.tables[0].max_records);
}
let table = unsafe { db.get_table_mut(0).unwrap() };
println!("表名: {}", table.def.name);
println!("记录大小: {}", table.def.record_size);
for (i, field) in table.def.fields.iter().enumerate() {
println!(
"字段 {}: 名称={}, 大小={}, 偏移={}",
i, field.name, field.size, field.offset
);
}
println!("=== 手动遍历表记录 ===");
let mut count = 0;
unsafe {
table
.iterate(|id, record_ptr| {
println!("记录 {} (ID: {}) 存在", count, id);
count += 1;
true
})
.unwrap();
}
println!("找到 {} 条记录", count);
let result = db.sql_query("SELECT * FROM TEST_TABLE").unwrap();
println!("查询结果行数: {}", result.row_count());
assert_eq!(result.row_count(), 5);
assert_eq!(result.column_count(), 5);
let result = db.sql_query("SELECT name, age FROM TEST_TABLE").unwrap();
assert_eq!(result.row_count(), 5);
assert_eq!(result.column_count(), 2);
let result = db
.sql_query("SELECT * FROM TEST_TABLE WHERE age > 25")
.unwrap();
assert_eq!(result.row_count(), 3);
let result = db
.sql_query("SELECT * FROM TEST_TABLE WHERE active = true ORDER BY age ASC")
.unwrap();
assert_eq!(result.row_count(), 3);
let result = db.sql_query("SELECT * FROM TEST_TABLE LIMIT 2").unwrap();
assert_eq!(result.row_count(), 2);
let result = db
.sql_query("SELECT * FROM TEST_TABLE WHERE active = false LIMIT 2")
.unwrap();
assert_eq!(result.row_count(), 2);
let result = db.sql_query("SELECT * FROM invalid_table");
assert!(result.is_err());
if let Err(err) = result {
assert!(matches!(err, RemDbError::TableNotFound));
}
let result = db.sql_query("SELECT invalid_field FROM TEST_TABLE");
assert!(result.is_err());
if let Err(err) = result {
assert!(matches!(err, RemDbError::FieldNotFound));
}
println!("=== 测试SQL INSERT语句 ===");
let result = db.sql_query("DELETE FROM TEST_TABLE");
assert!(result.is_ok(), "清空表应该成功");
let result = db.sql_query("INSERT INTO TEST_TABLE (id, name, age, active, created_at) VALUES (1, 'TestUser', 30, true, 1620000000000)");
if let Err(e) = &result {
println!("INSERT错误: {:?}", e);
}
assert!(result.is_ok(), "合法INSERT应该成功");
let result = db.sql_query("INSERT INTO TEST_TABLE (id, name, age, active, created_at) VALUES (1, 'DuplicateUser', 25, false, 1620000001000)");
assert!(result.is_err(), "重复主键INSERT应该失败");
if let Err(err) = result {
assert!(
matches!(err, RemDbError::DuplicateKey),
"重复主键应该返回DuplicateKey错误,实际返回: {:?}",
err
);
}
let result = db.sql_query(
"INSERT INTO TEST_TABLE (id, name, age, active, created_at) VALUES \
(2, 'User2', 20, true, 1620000002000), \
(3, 'User3', 25, false, 1620000003000), \
(1, 'AnotherDuplicate', 40, true, 1620000004000)",
);
assert!(result.is_err(), "包含重复主键的批量INSERT应该失败");
if let Err(err) = result {
assert!(
matches!(err, RemDbError::DuplicateKey),
"批量INSERT中的重复主键应该返回DuplicateKey错误"
);
}
let result = db.sql_query(
"INSERT IGNORE INTO TEST_TABLE (id, name, age, active, created_at) VALUES \
(10, 'User10', 30, true, 1620000005000), \
(1, 'DuplicateUser', 25, false, 1620000006000), \
(11, 'User11', 35, true, 1620000007000)",
);
assert!(result.is_ok(), "INSERT IGNORE应该成功,即使有重复键");
let result = db.sql_query("SELECT id FROM TEST_TABLE ORDER BY id");
assert!(result.is_ok(), "SELECT应该成功");
if let Ok(result_set) = result {
println!("实际查询到 {} 条记录", result_set.rows.len());
}
println!("=== 测试SQL UPDATE语句 ===");
let result = db.sql_query("UPDATE TEST_TABLE SET age = 35, active = false WHERE id = 1");
if let Err(e) = &result {
println!("UPDATE失败原因: {:?}", e);
}
assert!(result.is_ok(), "基本UPDATE应该成功");
let result = db.sql_query("SELECT age, active FROM TEST_TABLE WHERE id = 1");
assert!(result.is_ok(), "验证UPDATE结果的SELECT应该成功");
let result_set = result.unwrap();
assert_eq!(result_set.row_count(), 1, "UPDATE后应该找到1条记录");
let result = db.sql_query("UPDATE TEST_TABLE SET active = true");
assert!(result.is_ok(), "更新所有记录的UPDATE应该成功");
let result = db.sql_query("SELECT COUNT(*) FROM TEST_TABLE WHERE active = true");
assert!(result.is_ok(), "验证更新所有记录的SELECT应该成功");
let result = db.sql_query("UPDATE TEST_TABLE SET age = 100 WHERE id = 999");
assert!(result.is_ok(), "更新不存在记录的UPDATE应该成功(影响0行)");
let result = db.sql_query("UPDATE TEST_TABLE SET age = age +1, active = false WHERE id = 1");
assert!(result.is_ok(), " 值嵌套UPDATE应该成功");
let result = db.sql_query("SELECT age, active FROM TEST_TABLE WHERE id = 1");
assert!(result.is_ok(), "验证UPDATE结果的SELECT应该成功");
let result_set = result.unwrap();
assert_eq!(result_set.row_count(), 1, "UPDATE后应该找到1条记录");
remdb::reset_global_db();
}
#[test]
#[serial]
fn test_sql_having() {
setup_test_db();
let config = &TEST_DB;
let db = unsafe { init_global_db(config).unwrap() };
let _ = db.sql_query("DELETE FROM TEST_TABLE");
let inserts = [
"INSERT INTO TEST_TABLE (id, name, age, active, created_at) VALUES (1, 'Alice', 25, true, 1620000000000)",
"INSERT INTO TEST_TABLE (id, name, age, active, created_at) VALUES (2, 'Bob', 30, true, 1620000001000)",
"INSERT INTO TEST_TABLE (id, name, age, active, created_at) VALUES (3, 'Charlie', 35, false, 1620000002000)",
"INSERT INTO TEST_TABLE (id, name, age, active, created_at) VALUES (4, 'David', 20, true, 1620000003000)",
"INSERT INTO TEST_TABLE (id, name, age, active, created_at) VALUES (5, 'Eve', 40, false, 1620000004000)",
"INSERT INTO TEST_TABLE (id, name, age, active, created_at) VALUES (6, 'Frank', 30, false, 1620000005000)",
"INSERT INTO TEST_TABLE (id, name, age, active, created_at) VALUES (7, 'Grace', 25, true, 1620000006000)",
];
for insert in inserts {
let result = db.sql_query(insert);
assert!(result.is_ok(), "插入测试数据失败: {}", insert);
}
println!("=== 测试HAVING子句 ===");
println!("测试1: 基本HAVING子句");
let result = db
.sql_query(
"SELECT active, COUNT(*) as count FROM TEST_TABLE GROUP BY active HAVING count > 2",
)
.unwrap();
assert_eq!(result.column_count(), 2, "HAVING子句查询应该返回2列");
println!("测试2: HAVING子句与聚合函数");
let result = db
.sql_query("SELECT active, AVG(age) as avg_age FROM TEST_TABLE GROUP BY active HAVING AVG(age) > 25")
.unwrap();
assert_eq!(
result.column_count(),
2,
"HAVING子句与聚合函数查询应该返回2列"
);
println!("测试3: 复杂HAVING条件");
let result = db
.sql_query("SELECT active, COUNT(*) as count, AVG(age) as avg_age FROM TEST_TABLE GROUP BY active HAVING count > 2 AND avg_age < 35")
.unwrap();
assert_eq!(result.column_count(), 3, "复杂HAVING条件查询应该返回3列");
println!("测试4: HAVING与WHERE结合");
let result = db
.sql_query("SELECT active, COUNT(*) as count FROM TEST_TABLE WHERE age > 20 GROUP BY active HAVING count > 2")
.unwrap();
assert_eq!(result.column_count(), 2, "HAVING与WHERE结合查询应该返回2列");
remdb::reset_global_db();
}
#[test]
#[serial]
fn test_sql_window_functions() {
setup_test_db();
let config = &TEST_DB;
let db = unsafe { init_global_db(config).unwrap() };
let _ = db.sql_query("DELETE FROM TEST_TABLE");
let inserts = [
"INSERT INTO TEST_TABLE (id, name, age, active, created_at) VALUES (1, 'Alice', 25, true, 1620000000000)",
"INSERT INTO TEST_TABLE (id, name, age, active, created_at) VALUES (2, 'Bob', 30, true, 1620000001000)",
"INSERT INTO TEST_TABLE (id, name, age, active, created_at) VALUES (3, 'Charlie', 35, false, 1620000002000)",
"INSERT INTO TEST_TABLE (id, name, age, active, created_at) VALUES (4, 'David', 20, true, 1620000003000)",
"INSERT INTO TEST_TABLE (id, name, age, active, created_at) VALUES (5, 'Eve', 40, false, 1620000004000)",
"INSERT INTO TEST_TABLE (id, name, age, active, created_at) VALUES (6, 'Frank', 30, false, 1620000005000)",
"INSERT INTO TEST_TABLE (id, name, age, active, created_at) VALUES (7, 'Grace', 25, true, 1620000006000)",
];
for insert in inserts {
let result = db.sql_query(insert);
assert!(result.is_ok(), "插入测试数据失败: {}", insert);
}
println!("=== 测试窗口函数 ===");
println!("测试1: 基本窗口函数查询");
let result = db
.sql_query("SELECT id, name, age FROM TEST_TABLE ORDER BY age DESC")
.unwrap();
assert_eq!(result.column_count(), 3, "基本查询应该返回3列");
println!("测试2: 聚合函数查询");
let result = db.sql_query("SELECT COUNT(*) FROM TEST_TABLE").unwrap();
assert_eq!(result.column_count(), 1, "COUNT函数查询应该返回1列");
remdb::reset_global_db();
}
#[test]
#[serial]
fn test_sql_create_checkpoint() {
println!("=== 测试SQL CREATE CHECKPOINT语句解析 ===");
use remdb::sql::{parse_sql_query, QueryType};
let result = parse_sql_query("CREATE CHECKPOINT;");
assert!(result.is_ok(), "CREATE CHECKPOINT语句应该能够被解析");
let query = result.unwrap();
assert_eq!(
query.query_type,
QueryType::CreateCheckpoint,
"查询类型应该是CreateCheckpoint"
);
println!("CREATE CHECKPOINT语句解析成功");
}
remdb::table!(
HYBRID_TABLE,
10, primary_key: id,
fields: {
id: i32,
category: str(50),
price: f64,
vector: vector(3) }
);
remdb::database!(
HYBRID_DB,
tables: [HYBRID_TABLE],
total_memory: 1048576 );
#[test]
#[serial]
fn test_sql_hybrid_query() {
setup_test_db();
let db = unsafe { init_global_db(&HYBRID_DB).unwrap() };
println!("=== 测试1: 混合查询 - 结构化条件AND向量条件 ===");
let result1 = db
.sql_query("SELECT id, category, price FROM HYBRID_TABLE WHERE category = 'electronics' AND vector <-> [1.0, 2.0, 3.0] < 0.5")
.unwrap();
println!("结果行数: {}", result1.row_count());
assert_eq!(result1.row_count(), 0, "混合查询AND条件结果行数应该为0");
println!("\n=== 插入测试数据 ===");
let insert_result1 = db.sql_query("INSERT INTO HYBRID_TABLE (id, category, price, vector) VALUES (1, 'electronics', 999.99, [1.0, 2.0, 3.0])");
assert!(insert_result1.is_ok(), "插入数据1失败");
let insert_result2 = db.sql_query("INSERT INTO HYBRID_TABLE (id, category, price, vector) VALUES (2, 'electronics', 699.99, [1.1, 2.1, 3.1])");
assert!(insert_result2.is_ok(), "插入数据2失败");
let insert_result3 = db.sql_query("INSERT INTO HYBRID_TABLE (id, category, price, vector) VALUES (3, 'electronics', 399.99, [4.0, 5.0, 6.0])");
assert!(insert_result3.is_ok(), "插入数据3失败");
let insert_result4 = db.sql_query("INSERT INTO HYBRID_TABLE (id, category, price, vector) VALUES (4, 'furniture', 199.99, [7.0, 8.0, 9.0])");
assert!(insert_result4.is_ok(), "插入数据4失败");
let insert_result5 = db.sql_query("INSERT INTO HYBRID_TABLE (id, category, price, vector) VALUES (5, 'furniture', 499.99, [7.1, 8.1, 9.1])");
assert!(insert_result5.is_ok(), "插入数据5失败");
println!("\n=== 测试3: 插入数据后执行混合查询 - 结构化条件AND向量条件 ===");
let result3 = db
.sql_query("SELECT id, category, price FROM HYBRID_TABLE WHERE category = 'electronics' AND vector <-> [1.0, 2.0, 3.0] < 0.5")
.unwrap();
println!("结果行数: {}", result3.row_count());
assert!(result3.row_count() >= 2, "混合查询AND条件结果行数不足");
println!("\n=== 测试4: 插入数据后执行混合查询 - 结构化条件OR向量条件 ===");
let result4 = db
.sql_query("SELECT id, category, price FROM HYBRID_TABLE WHERE price > 500 OR vector <-> [7.0, 8.0, 9.0] < 0.5")
.unwrap();
println!("结果行数: {}", result4.row_count());
assert!(result4.row_count() >= 4, "混合查询OR条件结果行数不足");
remdb::reset_global_db();
}
#[test]
#[serial]
fn test_sql_join() {
setup_test_db();
let config = &TEST_DB;
let db = unsafe { init_global_db(config).unwrap() };
println!("=== 测试SQL JOIN查询 ===");
let _ = db.sql_query("DELETE FROM TEST_TABLE");
let _ = db.sql_query("DELETE FROM ORDERS_TABLE");
let user_inserts = [
"INSERT INTO TEST_TABLE (id, name, age, active, created_at) VALUES (1, 'Alice', 25, true, 1620000000000)",
"INSERT INTO TEST_TABLE (id, name, age, active, created_at) VALUES (2, 'Bob', 30, true, 1620000001000)",
"INSERT INTO TEST_TABLE (id, name, age, active, created_at) VALUES (3, 'Charlie', 35, false, 1620000002000)",
"INSERT INTO TEST_TABLE (id, name, age, active, created_at) VALUES (4, 'David', 22, true, 1620000003000)",
];
for insert in user_inserts {
let result = db.sql_query(insert);
assert!(result.is_ok(), "插入用户数据失败: {}", insert);
println!("插入用户数据成功: {}", insert);
}
let result = db.sql_query("SELECT * FROM TEST_TABLE");
assert!(result.is_ok(), "查询TEST_TABLE失败");
let result_set = result.unwrap();
println!("TEST_TABLE中的记录数: {}", result_set.row_count());
let order_inserts = [
"INSERT INTO ORDERS_TABLE (id, user_id, product, amount) VALUES (1, 1, 'Product A', 100)",
"INSERT INTO ORDERS_TABLE (id, user_id, product, amount) VALUES (2, 1, 'Product B', 200)",
"INSERT INTO ORDERS_TABLE (id, user_id, product, amount) VALUES (3, 2, 'Product C', 300)",
"INSERT INTO ORDERS_TABLE (id, user_id, product, amount) VALUES (4, 3, 'Product D', 400)",
"INSERT INTO ORDERS_TABLE (id, user_id, product, amount) VALUES (5, 5, 'Product E', 500)", ];
for insert in order_inserts {
let result = db.sql_query(insert);
assert!(result.is_ok(), "插入订单数据失败: {}", insert);
println!("插入订单数据成功: {}", insert);
}
let result = db.sql_query("SELECT * FROM ORDERS_TABLE");
assert!(result.is_ok(), "查询ORDERS_TABLE失败");
let result_set = result.unwrap();
println!("ORDERS_TABLE中的记录数: {}", result_set.row_count());
println!("=== 测试INNER JOIN ===");
let result = db.sql_query(
"SELECT u.name, o.product FROM TEST_TABLE u INNER JOIN ORDERS_TABLE o ON u.id = o.user_id",
);
assert!(result.is_ok(), "INNER JOIN查询失败");
let result_set = result.unwrap();
println!("INNER JOIN结果行数: {}", result_set.row_count());
assert!(result_set.row_count() > 0, "INNER JOIN应该返回至少一条记录");
println!("=== 测试LEFT JOIN ===");
let result = db.sql_query(
"SELECT u.name, o.product FROM TEST_TABLE u LEFT JOIN ORDERS_TABLE o ON u.id = o.user_id",
);
assert!(result.is_ok(), "LEFT JOIN查询失败");
let result_set = result.unwrap();
println!("LEFT JOIN结果行数: {}", result_set.row_count());
assert!(
result_set.row_count() >= user_inserts.len(),
"LEFT JOIN应该返回至少{}条记录(每个用户一条)",
user_inserts.len()
);
let mut has_david = false;
for i in 0..result_set.row_count() {
if let Some(row) = result_set.get_row(i) {
if let Ok(name_value) = row.get(0) {
if name_value.value_type == crate::DataType::VarChar
|| name_value.value_type == crate::DataType::Char
|| name_value.value_type == crate::DataType::Text
{
unsafe {
let name_str = core::str::from_utf8(&name_value.value.string)
.unwrap_or("")
.trim_end_matches(char::from(0));
if name_str == "David" {
has_david = true;
break;
}
}
}
}
}
}
assert!(has_david, "LEFT JOIN应该包含没有订单的用户David");
println!("=== 测试RIGHT JOIN ===");
let result = db.sql_query(
"SELECT u.name, o.product FROM TEST_TABLE u RIGHT JOIN ORDERS_TABLE o ON u.id = o.user_id",
);
assert!(result.is_ok(), "RIGHT JOIN查询失败");
let result_set = result.unwrap();
println!("RIGHT JOIN结果行数: {}", result_set.row_count());
assert_eq!(
result_set.row_count(),
order_inserts.len(),
"RIGHT JOIN应该返回{}条记录(每个订单一条)",
order_inserts.len()
);
let mut has_orphan_order = false;
for i in 0..result_set.row_count() {
if let Some(row) = result_set.get_row(i) {
if let Ok(product_value) = row.get(1) {
if product_value.value_type == crate::DataType::VarChar
|| product_value.value_type == crate::DataType::Char
|| product_value.value_type == crate::DataType::Text
{
unsafe {
let product_str = core::str::from_utf8(&product_value.value.string)
.unwrap_or("")
.trim_end_matches(char::from(0));
if product_str == "Product E" {
has_orphan_order = true;
break;
}
}
}
}
}
}
assert!(
has_orphan_order,
"RIGHT JOIN应该包含没有对应用户的订单Product E"
);
println!("=== 测试FULL JOIN ===");
let result = db.sql_query(
"SELECT u.name, o.product FROM TEST_TABLE u FULL JOIN ORDERS_TABLE o ON u.id = o.user_id",
);
assert!(result.is_ok(), "FULL JOIN查询失败");
let result_set = result.unwrap();
println!("FULL JOIN结果行数: {}", result_set.row_count());
assert!(
result_set.row_count() >= 6,
"FULL JOIN应该返回至少6条记录(4个用户 + 1个孤儿订单)"
);
let mut has_david_full = false;
let mut has_orphan_order_full = false;
for i in 0..result_set.row_count() {
if let Some(row) = result_set.get_row(i) {
if let Ok(name_value) = row.get(0) {
if name_value.value_type == crate::DataType::VarChar
|| name_value.value_type == crate::DataType::Char
|| name_value.value_type == crate::DataType::Text
{
unsafe {
let name_str = core::str::from_utf8(&name_value.value.string)
.unwrap_or("")
.trim_end_matches(char::from(0));
if name_str == "David" {
has_david_full = true;
}
}
}
}
if let Ok(product_value) = row.get(1) {
if product_value.value_type == crate::DataType::VarChar
|| product_value.value_type == crate::DataType::Char
|| product_value.value_type == crate::DataType::Text
{
unsafe {
let product_str = core::str::from_utf8(&product_value.value.string)
.unwrap_or("")
.trim_end_matches(char::from(0));
if product_str == "Product E" {
has_orphan_order_full = true;
}
}
}
}
}
}
assert!(has_david_full, "FULL JOIN应该包含没有订单的用户David");
assert!(
has_orphan_order_full,
"FULL JOIN应该包含没有对应用户的订单Product E"
);
println!("=== 测试JOIN带WHERE条件 ===");
let result = db.sql_query("SELECT u.name, o.product, o.amount FROM TEST_TABLE u INNER JOIN ORDERS_TABLE o ON u.id = o.user_id WHERE o.amount > 200");
assert!(result.is_ok(), "JOIN带WHERE条件查询失败");
let result_set = result.unwrap();
println!("JOIN带WHERE条件结果行数: {}", result_set.row_count());
println!("=== 测试JOIN带ORDER BY ===");
let result = db.sql_query("SELECT u.name, o.product, o.amount FROM TEST_TABLE u INNER JOIN ORDERS_TABLE o ON u.id = o.user_id ORDER BY o.amount DESC");
assert!(result.is_ok(), "JOIN带ORDER BY查询失败");
let result_set = result.unwrap();
println!("JOIN带ORDER BY结果行数: {}", result_set.row_count());
println!("=== 测试JOIN带LIMIT ===");
let result = db.sql_query("SELECT u.name, o.product FROM TEST_TABLE u INNER JOIN ORDERS_TABLE o ON u.id = o.user_id LIMIT 2");
assert!(result.is_ok(), "JOIN带LIMIT查询失败");
let result_set = result.unwrap();
println!("JOIN带LIMIT结果行数: {}", result_set.row_count());
assert!(
result_set.row_count() <= 2,
"JOIN带LIMIT 2应该返回最多2条记录"
);
println!("所有JOIN测试通过!");
remdb::reset_global_db();
}
#[test]
#[serial]
fn test_sql_distinct() {
println!("=== 测试SQL DISTINCT语句 ===");
setup_test_db();
let config = &TEST_DB;
let db = unsafe { init_global_db(config).unwrap() };
let _ = db.sql_query("DELETE FROM TEST_TABLE");
let inserts = [
"INSERT INTO TEST_TABLE (id, name, age, active, created_at) VALUES (1, 'Alice', 25, true, 1620000000000)",
"INSERT INTO TEST_TABLE (id, name, age, active, created_at) VALUES (2, 'Bob', 30, true, 1620000001000)",
"INSERT INTO TEST_TABLE (id, name, age, active, created_at) VALUES (3, 'Charlie', 35, false, 1620000002000)",
"INSERT INTO TEST_TABLE (id, name, age, active, created_at) VALUES (4, 'David', 25, true, 1620000003000)",
"INSERT INTO TEST_TABLE (id, name, age, active, created_at) VALUES (5, 'Eve', 30, false, 1620000004000)",
];
for insert in inserts {
let result = db.sql_query(insert);
assert!(result.is_ok(), "插入测试数据失败: {}", insert);
}
println!("测试1: 基本DISTINCT查询");
let result = db.sql_query("SELECT DISTINCT age FROM TEST_TABLE");
assert!(result.is_ok(), "基本DISTINCT查询失败");
let result_set = result.unwrap();
println!("基本DISTINCT查询结果行数: {}", result_set.row_count());
assert!(
result_set.row_count() <= inserts.len(),
"DISTINCT结果行数不能超过原表行数"
);
println!("测试2: DISTINCT与WHERE条件");
let result = db.sql_query("SELECT DISTINCT age FROM TEST_TABLE WHERE active = true");
assert!(result.is_ok(), "带WHERE条件的DISTINCT查询失败");
let result_set = result.unwrap();
println!(
"带WHERE条件的DISTINCT查询结果行数: {}",
result_set.row_count()
);
println!("测试3: DISTINCT与ORDER BY");
let result = db.sql_query("SELECT DISTINCT age FROM TEST_TABLE ORDER BY age DESC");
assert!(result.is_ok(), "带ORDER BY的DISTINCT查询失败");
let result_set = result.unwrap();
println!(
"带ORDER BY的DISTINCT查询结果行数: {}",
result_set.row_count()
);
println!("测试4: DISTINCT与LIMIT");
let result = db.sql_query("SELECT DISTINCT age FROM TEST_TABLE LIMIT 2");
assert!(result.is_ok(), "带LIMIT的DISTINCT查询失败");
let result_set = result.unwrap();
println!("带LIMIT的DISTINCT查询结果行数: {}", result_set.row_count());
assert!(
result_set.row_count() <= 2,
"带LIMIT 2的DISTINCT结果行数不能超过2"
);
println!("测试5: 多列DISTINCT");
let result = db.sql_query("SELECT DISTINCT age, active FROM TEST_TABLE");
assert!(result.is_ok(), "多列DISTINCT查询失败");
let result_set = result.unwrap();
println!("多列DISTINCT查询结果行数: {}", result_set.row_count());
remdb::reset_global_db();
}
#[test]
#[serial]
fn test_sql_aliases() {
setup_test_db();
let config = &TEST_DB;
let db = unsafe { init_global_db(config).unwrap() };
let _ = db.sql_query("DELETE FROM TEST_TABLE");
let insert = "INSERT INTO TEST_TABLE (id, name, age, active, created_at) VALUES (1, 'Alice', 25, true, 1620000000000)";
let result = db.sql_query(insert);
assert!(result.is_ok(), "插入测试数据失败: {}", insert);
let result = db.sql_query("SELECT name AS username, age AS user_age FROM TEST_TABLE");
assert!(result.is_ok(), "字段别名查询失败");
let result_set = result.unwrap();
assert_eq!(result_set.column_count(), 2, "字段别名查询应该返回2列");
let result = db.sql_query("SELECT t.name, t.age FROM TEST_TABLE t WHERE t.id = 1");
assert!(result.is_ok(), "表别名查询失败");
let result_set = result.unwrap();
assert_eq!(result_set.row_count(), 1, "表别名查询应该返回1行");
let result = db.sql_query("SELECT t.name AS username FROM TEST_TABLE t WHERE t.id = 1");
assert!(result.is_ok(), "混合别名查询失败");
let result_set = result.unwrap();
assert_eq!(result_set.column_count(), 1, "混合别名查询应该返回1列");
remdb::reset_global_db();
}
#[test]
#[serial]
fn test_sql_functions() {
setup_test_db();
let config = &TEST_DB;
let db = unsafe { init_global_db(config).unwrap() };
let _ = db.sql_query("DELETE FROM TEST_TABLE");
let inserts = [
"INSERT INTO TEST_TABLE (id, name, age, active, created_at) VALUES (1, 'Alice', 25, true, 1620000000000)",
"INSERT INTO TEST_TABLE (id, name, age, active, created_at) VALUES (2, 'Bob', 30, true, 1620000001000)",
"INSERT INTO TEST_TABLE (id, name, age, active, created_at) VALUES (3, 'Charlie', 35, false, 1620000002000)",
];
for insert in inserts {
let result = db.sql_query(insert);
assert!(result.is_ok(), "插入测试数据失败: {}", insert);
}
println!("测试COUNT函数");
let result = db.sql_query("SELECT COUNT(*) FROM TEST_TABLE");
assert!(result.is_ok(), "COUNT函数查询失败");
let result_set = result.unwrap();
assert_eq!(result_set.column_count(), 1, "COUNT函数应该返回1列");
let result = db.sql_query("SELECT COUNT(name) FROM TEST_TABLE");
assert!(result.is_ok(), "COUNT(field)函数查询失败");
let result = db.sql_query("SELECT COUNT(*) FROM TEST_TABLE WHERE active = true");
assert!(result.is_ok(), "COUNT与WHERE条件查询失败");
println!("测试SUM函数");
let result = db.sql_query("SELECT SUM(age) FROM TEST_TABLE");
assert!(result.is_ok(), "SUM函数查询失败");
println!("测试AVG函数");
let result = db.sql_query("SELECT AVG(age) FROM TEST_TABLE");
assert!(result.is_ok(), "AVG函数查询失败");
println!("测试MIN函数");
let result = db.sql_query("SELECT MIN(age) FROM TEST_TABLE");
assert!(result.is_ok(), "MIN函数查询失败");
println!("测试MAX函数");
let result = db.sql_query("SELECT MAX(age) FROM TEST_TABLE");
assert!(result.is_ok(), "MAX函数查询失败");
println!("测试多函数组合");
let result = db.sql_query("SELECT MIN(age), MAX(age), AVG(age) FROM TEST_TABLE");
assert!(result.is_ok(), "多函数组合查询失败");
let result_set = result.unwrap();
assert_eq!(result_set.column_count(), 3, "多函数组合应该返回3列");
remdb::reset_global_db();
}
#[test]
#[serial]
fn test_sql_statistical_functions() {
setup_test_db();
let config = &TEST_DB;
let db = unsafe { init_global_db(config).unwrap() };
let _ = db.sql_query("DELETE FROM TEST_TABLE");
let inserts = [
"INSERT INTO TEST_TABLE (id, name, age, active, created_at) VALUES (1, 'Alice', 25, true, 1620000000000)",
"INSERT INTO TEST_TABLE (id, name, age, active, created_at) VALUES (2, 'Bob', 30, true, 1620000001000)",
"INSERT INTO TEST_TABLE (id, name, age, active, created_at) VALUES (3, 'Charlie', 35, false, 1620000002000)",
"INSERT INTO TEST_TABLE (id, name, age, active, created_at) VALUES (4, 'David', 20, true, 1620000003000)",
"INSERT INTO TEST_TABLE (id, name, age, active, created_at) VALUES (5, 'Eve', 40, false, 1620000004000)",
];
for insert in inserts {
let result = db.sql_query(insert);
assert!(result.is_ok(), "插入测试数据失败: {}", insert);
}
println!("测试VAR函数");
let result = db.sql_query("SELECT VAR(age) FROM TEST_TABLE");
assert!(result.is_ok(), "VAR函数查询失败");
println!("测试VAR_SAMP函数");
let result = db.sql_query("SELECT VAR_SAMP(age) FROM TEST_TABLE");
assert!(result.is_ok(), "VAR_SAMP函数查询失败");
println!("测试STDDEV函数");
let result = db.sql_query("SELECT STDDEV(age) FROM TEST_TABLE");
assert!(result.is_ok(), "STDDEV函数查询失败");
println!("测试STDDEV_SAMP函数");
let result = db.sql_query("SELECT STDDEV_SAMP(age) FROM TEST_TABLE");
assert!(result.is_ok(), "STDDEV_SAMP函数查询失败");
remdb::reset_global_db();
}
#[test]
#[serial]
fn test_sql_aggregate_functions() {
setup_test_db();
let config = &TEST_DB;
let db = unsafe { init_global_db(config).unwrap() };
let _ = db.sql_query("DELETE FROM TEST_TABLE");
let inserts = [
"INSERT INTO TEST_TABLE (id, name, age, active, created_at) VALUES (1, 'Alice', 25, true, 1620000000000)",
"INSERT INTO TEST_TABLE (id, name, age, active, created_at) VALUES (2, 'Bob', 30, true, 1620000001000)",
"INSERT INTO TEST_TABLE (id, name, age, active, created_at) VALUES (3, 'Charlie', 35, false, 1620000002000)",
"INSERT INTO TEST_TABLE (id, name, age, active, created_at) VALUES (4, 'David', 20, true, 1620000003000)",
"INSERT INTO TEST_TABLE (id, name, age, active, created_at) VALUES (5, 'Eve', 40, false, 1620000004000)",
];
for insert in inserts {
let result = db.sql_query(insert);
assert!(result.is_ok(), "插入测试数据失败: {}", insert);
}
println!("测试1: 基本聚合函数");
let result = db.sql_query("SELECT MIN(age), MAX(age), AVG(age) FROM TEST_TABLE");
assert!(result.is_ok(), "基本聚合函数查询失败");
let result_set = result.unwrap();
assert_eq!(result_set.column_count(), 3, "基本聚合函数应该返回3列");
println!("测试2: 聚合函数与WHERE条件");
let result = db.sql_query("SELECT MIN(age), MAX(age) FROM TEST_TABLE WHERE active = true");
assert!(result.is_ok(), "聚合函数与WHERE条件查询失败");
println!("测试3: 聚合函数与ORDER BY");
let result =
db.sql_query("SELECT age, COUNT(*) FROM TEST_TABLE GROUP BY age ORDER BY age DESC");
assert!(result.is_ok(), "聚合函数与ORDER BY查询失败");
println!("测试4: 聚合函数与LIMIT");
let result =
db.sql_query("SELECT age, COUNT(*) FROM TEST_TABLE GROUP BY age ORDER BY age DESC LIMIT 2");
assert!(result.is_ok(), "聚合函数与LIMIT查询失败");
remdb::reset_global_db();
}
#[test]
#[serial]
fn test_sql_group_by() {
setup_test_db();
let config = &TEST_DB;
let db = unsafe { init_global_db(config).unwrap() };
let test_data = [
(1, "Alice", 25, true, 1620000000000),
(2, "Bob", 30, true, 1620000001000),
(3, "Charlie", 35, false, 1620000002000),
(4, "David", 22, true, 1620000003000),
(5, "Eve", 28, false, 1620000004000),
(6, "Frank", 30, false, 1620000005000),
(7, "Grace", 25, true, 1620000006000),
];
#[repr(C)]
struct TestRecord {
id: i32, name: [u8; 32], age: i8, active: u8, _padding: [u8; 2], created_at: u64, }
for (id, name, age, active, created_at) in test_data {
let mut record = TestRecord {
id,
name: [0u8; 32],
age,
active: if active { 1 } else { 0 }, _padding: [0u8; 2], created_at,
};
let name_bytes = name.as_bytes();
record.name[..name_bytes.len()].copy_from_slice(name_bytes);
let insert_id = unsafe {
db.get_table_mut(0)
.unwrap()
.insert(&record as *const _ as *const u8)
.unwrap()
};
assert!(insert_id < config.tables[0].max_records);
}
println!("=== 测试GROUP BY功能 ===");
println!("测试1: 基本GROUP BY查询");
let result = db
.sql_query("SELECT active, COUNT(*) FROM TEST_TABLE GROUP BY active")
.unwrap();
assert_eq!(result.column_count(), 2, "基本GROUP BY查询应该返回2列");
println!("基本GROUP BY查询结果行数: {}", result.row_count());
println!("测试2: 带WHERE条件的GROUP BY查询");
let result = db
.sql_query("SELECT age, COUNT(*) FROM TEST_TABLE WHERE active = true GROUP BY age")
.unwrap();
assert_eq!(
result.column_count(),
2,
"带WHERE条件的GROUP BY查询应该返回2列"
);
println!("带WHERE条件的GROUP BY查询结果行数: {}", result.row_count());
println!("测试3: 带聚合函数的GROUP BY查询");
let result = db.sql_query("SELECT active, COUNT(*), SUM(age), AVG(age), MIN(age), MAX(age) FROM TEST_TABLE GROUP BY active").unwrap();
assert_eq!(
result.column_count(),
6,
"带聚合函数的GROUP BY查询应该返回6列"
);
assert_eq!(result.row_count(), 2, "active字段只有两个值,应该返回2行");
println!("测试4: 带ORDER BY的GROUP BY查询");
let result = db
.sql_query("SELECT age, COUNT(*) FROM TEST_TABLE GROUP BY age ORDER BY age DESC")
.unwrap();
assert_eq!(
result.column_count(),
2,
"带ORDER BY的GROUP BY查询应该返回2列"
);
println!("带ORDER BY的GROUP BY查询结果行数: {}", result.row_count());
println!("测试5: 多列GROUP BY查询");
let result = db
.sql_query("SELECT active, age, COUNT(*) FROM TEST_TABLE GROUP BY active, age")
.unwrap();
assert_eq!(result.column_count(), 3, "多列GROUP BY查询应该返回3列");
println!("多列GROUP BY查询结果行数: {}", result.row_count());
println!("测试6: GROUP BY与HAVING结合查询");
let result = db
.sql_query(
"SELECT active, COUNT(*) as count FROM TEST_TABLE GROUP BY active HAVING count > 2",
)
.unwrap();
assert_eq!(
result.column_count(),
2,
"GROUP BY与HAVING结合查询应该返回2列"
);
println!("GROUP BY与HAVING结合查询结果行数: {}", result.row_count());
println!("测试7: 单列GROUP BY查询");
let result = db
.sql_query("SELECT age FROM TEST_TABLE GROUP BY age")
.unwrap();
assert_eq!(result.column_count(), 1, "单列GROUP BY查询应该返回1列");
println!("单列GROUP BY查询结果行数: {}", result.row_count());
remdb::reset_global_db();
}