100 lines
3.8 KiB
Rust
100 lines
3.8 KiB
Rust
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();
|
|
}
|