Enhance OML knowledge SQL handling and prefer local sqlite authority#97
Enhance OML knowledge SQL handling and prefer local sqlite authority#97zwk4zhendeC wants to merge 2 commits into
Conversation
Codecov Report❌ Patch coverage is
📢 Thoughts on this report? Let us know! |
seeker-zuo
left a comment
There was a problem hiding this comment.
整体评价
方向正确,功能上能解决 #96 的问题。但代码质量和性能有几处需要改进后再合并。
主要问题
1. 代码重复:KnowdbProbe 等结构体在三处重复定义
KnowdbProviderProbe、KnowdbProbe、KnowdbTableProbe 在以下三个文件中几乎完全重复:
src/facade/engine.rs:71-87src/facade/rescue.rs:23-44src/knowledge/mod.rs:44-58
应该提取到 src/knowledge/mod.rs 并 pub(crate) 导出,让调用方复用。
2. KnowdbHandler 新增方法未被使用
authority_uri()、local_tables()、has_local_tables() 已添加,但 engine.rs 和 rescue.rs 各自独立调用 load_local_table_names() 重新解析 toml,导致 knowdb.toml 被解析两次。应该通过 KnowdbHandler 获取这些信息。
3. first_table_name() SQL 解析过于脆弱 (sql.rs:45-55)
用字符串匹配 from 提取表名,以下场景会出错:
- 子查询:
SELECT * FROM (SELECT * FROM real_table)→ 匹配到内层 FROM - JOIN:
SELECT * FROM t1 JOIN t2→ 只拿到 t1 - 字符串中含 "from":
SELECT 'from' AS x FROM my_table→ 匹配错误
建议至少对子查询和 JOIN 场景做防御性处理,或在匹配失败时 warn 日志。
4. 性能:每次查询都做 to_ascii_lowercase() 堆分配
first_table_name() 中对每条 SQL 执行 sql.to_ascii_lowercase(),这是热路径(每条 event 可能触发多次),会造成不必要的堆分配。建议改为逐字节遍历做 case-insensitive 匹配。
5. 性能:热路径上的 RwLock::read()
local_sqlite_for_table() 每次调用都获取 RwLock::read()。99% 的查询来自外部 provider 不会命中本地表,但每条 SQL 仍需走一遍原子操作。建议初始化时把 HashSet<String> 放到 Arc 里,查询路径只做 Arc::clone + 无锁查找。
6. 性能:ThreadClonedMDB 每次查询创建新连接
每次命中本地表都调用 ThreadClonedMDB::from_authority() 创建新连接,高频场景下开销较大。建议缓存连接或复用。
次要问题
7. should_rebuild_local_authority 命名误导
PG/MySQL 时返回 false(不重建),但调用方通过 || !local_tables.is_empty() 覆盖了结果,实际语义是 "是否应该保留旧 authority 文件"。建议改名或反转返回值。
8. engine.rs 与 rescue.rs 的 authority URI 读写模式不一致
engine.rs:492:readonly_authority_uri()— 只读rescue.rs:128:authority_uri.clone()— 读写
如果是有意为之,需要注释说明原因;如果是遗漏,应该统一。
9. 缺少自动化测试
first_table_name()、路由逻辑、should_rebuild_local_authority() 等关键函数均无单元测试。手动验证能证明本次正确,但后续重构容易引入回归。
建议处理顺序
| 优先级 | 事项 |
|---|---|
| 🔴 | 消除三处结构体重复,提取到 knowledge/mod.rs |
| 🔴 | 调用方改用 KnowdbHandler 获取 local_tables,避免重复解析 |
| 🔴 | 去掉 to_ascii_lowercase() 每查询一次堆分配 |
| 🔴 | 去掉热路径 RwLock::read(),改用 Arc<HashSet> 无锁查找 |
| 🟡 | 缓存 ThreadClonedMDB 连接或将创建移到调用方 |
| 🟡 | 改进 first_table_name() 的 SQL 解析鲁棒性 |
| 🟢 | 添加关键路径单元测试 |
| 🟢 | 统一 URI 读写模式 / 改进函数命名 |
支持 KnowDB provider 与本地 tables 共存时优先命中 sqlite authority
背景
当前 KnowDB 在
knowdb.toml同时包含:[[tables]](CSV -> authority.sqlite)时,运行时只会激活外部 provider,导致:
.run/authority.sqlite在部分路径下还会被误删这会让本地静态知识表无法在共存场景下发挥作用。
问题表现
以示例
tmp/knowdb_pg_sqlite为例:knowdb.toml同时包含:[provider] kind = "postgres"[[tables]] name = "local_asset_data"对应 OML:
期望行为:
asset_data继续走 PostgreSQLlocal_asset_data优先走本地 sqlite authority旧行为:
local_asset_data仍然发往 PostgreSQL解决方案
本次改动分为两层:
1. 启动阶段:即使存在 provider,也先构建本地 authority
在引擎初始化时:
knowdb.toml中存在本地[[tables]][provider].run/authority.sqlite同时:
postgres/mysql时,不再无条件删除authority.sqlite这保证了本地表在运行时始终有可用的 authority 数据源。
2. 运行阶段:按表名路由,本地表优先走 sqlite
在 OML SQL evaluator 中增加本地 sqlite 优先路由:
knowdb.toml中[[tables]]的本地表名单FROM <table>因此实现了:
同时包含的改动(截至
1234c99,包含)1. 增强 OML SQL 表达能力
group_concat(distinct ...)where field in (...)in(...)与in (...)@ref引用前序 OML 字段2. 空值处理优化
NULL时,不再把field: null写入最终结果null,则直接跳过查询,避免无意义请求和报错3.
take(...)语义修复take现在可以消费前序 OML 已经写入dst的字段read的上下文可见性保持一致主要改动点
引擎 / rescue 初始化
src/facade/engine.rssrc/facade/rescue.rs职责:
[[tables]]是否存在KnowDB handler
src/knowledge/mod.rs职责:
OML SQL evaluator
crates/wp-oml/src/core/evaluator/query/sql.rs职责:
OML 最终结果写入
crates/wp-oml/src/core/evaluator/extract/operations/other.rs职责:
Value::Null,避免输出field: nullSQL parser
crates/wp-oml/src/parser/sql_prm.rs职责:
group_concat(distinct ...)IN (...)@ref验证
已完成验证包括:
编译验证
示例验证
在:
/Users/zwk/src_code/wp-labs/warp-parse执行:
验证结果:
asset_data继续走 PostgreSQLlocal_asset_data已优先命中 sqlite authority输出文件中已出现:
{ "src_ip":"10.0.220.200", "dist_ip":"10.0.220.201", "pg_asset_name":"香港监控服务主机", "sqlite_asset_name":"1香港监控服务主机", "sqlite_asset_list":"1香港监控服务主机,1广东监控服务主机" }关联 Issue