use super::*; use std::{hint::black_box, time::Instant}; #[test] fn json_constraint_keeps_validation_without_constructing_a_value() { let directory = Directory::new(); runtime() .run(async |scope| { let database = Database::open(&directory.0, options(), scope) .await .unwrap(); let mut executor = database.executor().await.unwrap(); let sources = [ "null".to_owned(), "1e9999".into(), r#"{"name":"雪\n🙂","values":[1,true]}"#.into(), r#"{"a":1,"a":2}"#.into(), r#""\ud800""#.into(), "[1,]".into(), "null true".into(), "[".repeat(257) + &"]".repeat(257), format!("[{}0]", "0,".repeat(65535)), format!("\"{}\"", "x".repeat(16 * 1024 * 1024)), ]; for source in sources { let expected = dever_runtime::wire::json::Json::parse(&source).is_ok(); let actual = executor .query( scope, "SELECT _dever_json(?1)", vec![Parameter::Text(source)], 1, |row| row.get::<_, bool>(0), ) .await .unwrap(); assert_eq!(actual, [expected]); } }) .unwrap(); } #[test] #[ignore = "explicit release SQL validation performance probe"] fn sqlite_json_check_cost() { let directory = Directory::new(); let runtime = runtime(); runtime .run(async |scope| { let database = Database::open(&directory.0, options(), scope) .await .unwrap(); let mut executor = database.executor().await.unwrap(); executor .initialize(scope, "CREATE TABLE documents (body TEXT NOT NULL)") .await .unwrap(); println!("\ncase,sample,iterations,elapsed_ns,checksum"); for (bytes, iterations) in [(64, 100), (4096, 100), (65536, 10)] { executor .execute(scope, "DELETE FROM documents", vec![]) .await .unwrap(); let source = format!("\"{}\"", "x".repeat(bytes - 2)); executor .execute( scope, "WITH RECURSIVE rows(id) AS (SELECT 1 UNION ALL SELECT id+1 FROM rows WHERE id<256) INSERT INTO documents SELECT ?1 FROM rows", vec![Parameter::Text(source)], ) .await .unwrap(); // 实际列逐行调用约束;避免常量折叠只验证一次参数。 for sample in 0..16 { let start = Instant::now(); let mut checksum = 0i64; for _ in 0..iterations { let result = executor .query( scope, "SELECT SUM(_dever_json(body)) FROM documents", vec![], 1, |row| row.get::<_, i64>(0), ) .await .unwrap(); checksum += black_box(result[0]); } let elapsed = start.elapsed().as_nanos(); assert_eq!(checksum, iterations * 256); if sample != 0 { println!("sqlite_json_check_{bytes},{},{iterations},{elapsed},{checksum}", sample - 1); } } } }) .unwrap(); }