use remdb::{
config::{DbConfig, DefaultMemoryAllocator, LogMode, WALConfig},
sql::execute_query,
sql::parse_sql_query,
RemDb,
};
use serial_test::serial;
static mut DB_MEMORY: [u8; 4 * 1024 * 1024] = [0; 4 * 1024 * 1024];
static DEFAULT_ALLOCATOR: DefaultMemoryAllocator = DefaultMemoryAllocator;
static TEST_CONFIG: DbConfig = DbConfig {
total_memory: 1024 * 1024, default_max_records: 100,
low_power_mode_supported: false,
low_power_max_records: Some(50),
wal_config: WALConfig {
log_path: "",
log_mode: LogMode::Sync,
checkpoint_interval_ms: 60000,
log_file_size_limit: 16 * 1024 * 1024,
log_prealloc_size: 0,
log_segment_size: 16 * 1024 * 1024,
retained_checkpoints: 1,
max_consecutive_invalid: 100,
skip_threshold: 1000,
skip_block_size: 1024 * 1024,
max_skip_attempts: 3,
compression_type: remdb::config::WALCompressionType::None,
compression_level: 3,
},
tables: Vec::new(),
memory_allocator: &DEFAULT_ALLOCATOR,
time_series_defaults: remdb::time_series::TimeSeriesConfig {
partition_duration_secs: 3600,
retention_period_secs: 86400,
max_partitions: 100,
compression: remdb::time_series::CompressionType::None,
},
#[cfg(feature = "pubsub")]
pubsub_config: None,
#[cfg(feature = "ha")]
ha_config: None,
model_worker_config: remdb::config::ModelWorkerConfig::DEFAULT,
};
#[test]
#[serial]
fn test_like_operator() {
unsafe {
DB_MEMORY.fill(0);
remdb::memory::allocator::init_global_allocator(DB_MEMORY.as_mut_ptr(), DB_MEMORY.len())
.expect("init_global_allocator failed");
}
let mut db = RemDb::new(&TEST_CONFIG);
db.init().expect("db init failed");
let create_table_sql = "CREATE TABLE test (id INTEGER PRIMARY KEY, name VARCHAR(255));";
let create_query = parse_sql_query(create_table_sql).expect("parse CREATE TABLE failed");
execute_query(&mut db, &create_query).expect("execute CREATE TABLE failed");
let insert_sql_1 = "INSERT INTO test (id, name) VALUES (1, 'test');";
let insert_query_1 = parse_sql_query(insert_sql_1).expect("parse INSERT 1 failed");
execute_query(&mut db, &insert_query_1).expect("execute INSERT 1 failed");
let insert_sql_2 = "INSERT INTO test (id, name) VALUES (2, 'testing');";
let insert_query_2 = parse_sql_query(insert_sql_2).expect("parse INSERT 2 failed");
execute_query(&mut db, &insert_query_2).expect("execute INSERT 2 failed");
let insert_sql_3 = "INSERT INTO test (id, name) VALUES (3, 'test123');";
let insert_query_3 = parse_sql_query(insert_sql_3).expect("parse INSERT 3 failed");
execute_query(&mut db, &insert_query_3).expect("execute INSERT 3 failed");
let insert_sql_4 = "INSERT INTO test (id, name) VALUES (4, '123test');";
let insert_query_4 = parse_sql_query(insert_sql_4).expect("parse INSERT 4 failed");
execute_query(&mut db, &insert_query_4).expect("execute INSERT 4 failed");
let insert_sql_5 = "INSERT INTO test (id, name) VALUES (5, '100%');";
let insert_query_5 = parse_sql_query(insert_sql_5).expect("parse INSERT 5 failed");
execute_query(&mut db, &insert_query_5).expect("execute INSERT 5 failed");
let sql1 = "SELECT * FROM test WHERE name LIKE 'test%';";
let query1 = parse_sql_query(sql1).expect("parse SELECT 1 failed");
let result1 = execute_query(&mut db, &query1).expect("execute SELECT 1 failed");
assert_eq!(result1.rows.len(), 3);
let sql2 = "SELECT * FROM test WHERE name LIKE '%test';";
let query2 = parse_sql_query(sql2).expect("parse SELECT 2 failed");
let result2 = execute_query(&mut db, &query2).expect("execute SELECT 2 failed");
assert_eq!(result2.rows.len(), 2);
let sql3 = "SELECT * FROM test WHERE name LIKE '%test%';";
let query3 = parse_sql_query(sql3).expect("parse SELECT 3 failed");
let result3 = execute_query(&mut db, &query3).expect("execute SELECT 3 failed");
assert_eq!(result3.rows.len(), 4);
let sql4 = "SELECT * FROM test WHERE name LIKE '_test';";
let query4 = parse_sql_query(sql4).expect("parse SELECT 4 failed");
let result4 = execute_query(&mut db, &query4).expect("execute SELECT 4 failed");
assert_eq!(result4.rows.len(), 0);
let sql5 = "SELECT * FROM test WHERE name LIKE '100\\%';";
let query5 = parse_sql_query(sql5).expect("parse SELECT 5 failed");
let result5 = execute_query(&mut db, &query5).expect("execute SELECT 5 failed");
assert_eq!(result5.rows.len(), 1); }
#[test]
#[serial]
fn test_like_pattern_match_various_cases() {
unsafe {
DB_MEMORY.fill(0);
remdb::memory::allocator::init_global_allocator(DB_MEMORY.as_mut_ptr(), DB_MEMORY.len())
.expect("init_global_allocator failed");
}
let mut db = RemDb::new(&TEST_CONFIG);
db.init().expect("db init failed");
let create_table_sql = "CREATE TABLE test (id INTEGER PRIMARY KEY, name VARCHAR(255));";
let create_query = parse_sql_query(create_table_sql).expect("parse CREATE TABLE failed");
execute_query(&mut db, &create_query).expect("execute CREATE TABLE failed");
let insert_sql = "INSERT INTO test (id, name) VALUES (1, 'test');";
let insert_query = parse_sql_query(insert_sql).expect("parse INSERT failed");
execute_query(&mut db, &insert_query).expect("execute INSERT failed");
let test_cases = vec![
("test%", true), ("%test", true), ("%test%", true), ("test", true), ("testing", false), ("%", true), ("_est", true), ("t_st", true), ("\\%", false), ];
for (pattern, expected) in test_cases {
let sql = format!("SELECT * FROM test WHERE name LIKE '{}';", pattern);
let query = parse_sql_query(&sql).expect("parse SELECT failed");
let result = execute_query(&mut db, &query).expect("execute SELECT failed");
let actual = !result.rows.is_empty();
assert_eq!(
actual, expected,
"Pattern '{}' failed: expected {}, got {}",
pattern, expected, actual
);
}
}