用李红艳先生的DuckDB luajit插件批量计算数独

📅 2026/8/9 6:10:09
用李红艳先生的DuckDB luajit插件批量计算数独
这个插件比名字类似的lua插件功能强大太多不要装错。存储库地址https://github.com/alitrack/duckdb-luajit1.安装插件memory D force install luajit from community; memory D load luajit;2.拉取远程duckdb-luajit现成库https://github.com/alitrack/duckdb-luajit-libs--列举可用模块 memory D SELECT * FROM luajit_module(mode : list_remote); ┌─────────┬─────────────┬─────────────┬────────────────────┬────────────────────────────────────────────────┬──────────┐ │ ok │ mode │ phase │ message │ detail │ sql_name │ │ boolean │ varchar │ varchar │ varchar │ varchar │ varchar │ ├─────────┼─────────────┼─────────────┼────────────────────┼────────────────────────────────────────────────┼──────────┤ │ true │ list_remote │ list_remote │ duckdb-luajit-libs │ available libs:\n dicom — libs/datasource/dic │ │ │ │ │ │ │ om.lua\n dirscan — libs/datasource/dirscan.lu │ │ │ │ │ │ │ a\n export — libs/export/export.lua\n json — │ │ │ │ │ │ │ libs/parser/json.lua\n base64 — libs/udf/bas │ │ │ │ │ │ │ e64.lua\n crc32 — libs/udf/crc32.lua\n uuid │ │ │ │ │ │ │ — libs/udf/uuid.lua\n html_escape — libs/udf/ │ │ │ │ │ │ │ html_escape.lua\n mcp_demo — libs/mcp/mcp-ser │ │ │ │ │ │ │ ver.sql\n │ │ └─────────┴─────────────┴─────────────┴────────────────────┴────────────────────────────────────────────────┴──────────┘ --拉取base64 udf memory D SELECT * FROM luajit_module(mode : install, sql_name : base64); ┌─────────┬─────────┬─────────┬──────────────────────────────────────┬──────────────────────────────────────┬──────────┐ │ ok │ mode │ phase │ message │ detail │ sql_name │ │ boolean │ varchar │ varchar │ varchar │ varchar │ varchar │ ├─────────┼─────────┼─────────┼──────────────────────────────────────┼──────────────────────────────────────┼──────────┤ │ true │ install │ install │ installed base64 (UDF) — cached at │ luajit_table(base64) or luajit_s( │ base64 │ │ │ │ │ ~/.duckdb/luajit-libs/base64.lua │ base64, ...) │ │ └─────────┴─────────┴─────────┴──────────────────────────────────────┴──────────────────────────────────────┴──────────┘ --使用base64 udf成功 memory D SELECT luajit_s(base64, hello); ┌─────────────────────────────┐ │ luajit_s(base64, hello) │ │ varchar │ ├─────────────────────────────┤ │ aGVsbG8 │ └─────────────────────────────┘错误的用法尝试--希望安装mcp_demo报错 memory D SELECT * FROM luajit_module(mode : install, sql_name : mcp_demo); ┌─────────┬─────────┬─────────┬───────────────────────────────────────────────────────────────────┬─────────┬──────────┐ │ ok │ mode │ phase │ message │ detail │ sql_name │ │ boolean │ varchar │ varchar │ varchar │ varchar │ varchar │ ├─────────┼─────────┼─────────┼───────────────────────────────────────────────────────────────────┼─────────┼──────────┤ │ false │ install │ │ install mcp_demo: [string -- lib: mcp_demo...]:28: expec │ │ mcp_demo │ │ │ │ │ ted near * │ │ │ └─────────┴─────────┴─────────┴───────────────────────────────────────────────────────────────────┴─────────┴──────────┘ --拉取sudoku失败第一次是网络问题第二次网络正常后说不在索引中 memory D SELECT * FROM luajit_module(mode : install, sql_name : sudoku); ┌─────────┬─────────┬─────────┬───────────────────────────────────────────────────────────────────┬─────────┬──────────┐ │ ok │ mode │ phase │ message │ detail │ sql_name │ │ boolean │ varchar │ varchar │ varchar │ varchar │ varchar │ ├─────────┼─────────┼─────────┼───────────────────────────────────────────────────────────────────┼─────────┼──────────┤ │ false │ install │ │ install sudoku failed: IO Error: Timeout was reached error for │ │ sudoku │ │ │ │ │ HTTP HEAD to https://raw.githubusercontent.com/alitrack/duckdb-l │ │ │ │ │ │ │ uajit-libs/main/INDEX │ │ │ └─────────┴─────────┴─────────┴───────────────────────────────────────────────────────────────────┴─────────┴──────────┘ memory D SELECT * FROM luajit_module(mode : install, sql_name : sudoku); ┌─────────┬─────────┬─────────┬──────────────────────────────────────────────────────────┬─────────┬──────────┐ │ ok │ mode │ phase │ message │ detail │ sql_name │ │ boolean │ varchar │ varchar │ varchar │ varchar │ varchar │ ├─────────┼─────────┼─────────┼──────────────────────────────────────────────────────────┼─────────┼──────────┤ │ false │ install │ │ install sudoku failed: lib sudoku not found in INDEX │ │ sudoku │ └─────────┴─────────┴─────────┴──────────────────────────────────────────────────────────┴─────────┴──────────┘实地查看索引内容确实不存在一个sudoku udfls ~/.duckdb/luajit-libs/ INDEX base64.lua mcp_demo.lua rootDESKTOP-59T6U68:/mnt/c/d# cat ~/.duckdb/luajit-libs/INDEX dicom|libs/datasource/dicom.lua dirscan|libs/datasource/dirscan.lua export|libs/export/export.lua json|libs/parser/json.lua base64|libs/udf/base64.lua crc32|libs/udf/crc32.lua uuid|libs/udf/uuid.lua html_escape|libs/udf/html_escape.lua mcp_demo|libs/mcp/mcp-server.sql考虑到国内上github.com经常网络出错趁早把存储库整个下载到本地duckdb-luajit-libs-main目录下。然后复制mcp-server.sql中的语句-- 2. 注册 Lua UDF: 数独求解 (模块文件 sudoku.lua 需同目录, 或改用 install 协议从本仓库拉) memory D SELECT * FROM luajit_module(mode : compile, sql_name : sudoku_solve, source : local s dofile(duckdb-luajit-libs-main/libs/mcp/sudoku.lua) return function(x) return s.solve(x) end); ┌─────────┬─────────┬─────────┬─────────┬─────────┬──────────────┐ │ ok │ mode │ phase │ message │ detail │ sql_name │ │ boolean │ varchar │ varchar │ varchar │ varchar │ varchar │ ├─────────┼─────────┼─────────┼─────────┼─────────┼──────────────┤ │ true │ compile │ compile │ OK │ │ sudoku_solve │ └─────────┴─────────┴─────────┴─────────┴─────────┴──────────────┘ memory D SELECT luajit_s(sudoku_solve, 000001002000020030004500600007600050080090006100005800001004000070900003400030020) AS r; ┌───────────────────────────────────────────────────────────────────────────────────┐ │ r │ │ varchar │ ├───────────────────────────────────────────────────────────────────────────────────┤ │ 359461782716829534824573619947682351583197246162345897631254978275918463498736125 │ └───────────────────────────────────────────────────────────────────────────────────┘ memory D .timer on memory D select count(*) from read_csv(sudoku17.txt); ┌──────────────┐ │ count_star() │ │ int64 │ ├──────────────┤ │ 49150 │ └──────────────┘ Run Time (s): real 0.075 user 0.007009 sys 0.014781 memory D with a(i) as(select * from read_csv(sudoku17.txt) limit 3)select luajit_s(sudoku_solve,i)from a; ┌───────────────────────────────────────────────────────────────────────────────────┐ │ luajit_s(sudoku_solve, i) │ │ varchar │ ├───────────────────────────────────────────────────────────────────────────────────┤ │ 793684512486512937125973846932751684578246391641398725319465278857129463264837159 │ │ 673894512912735486845612973798261354526473891134589267469128735287356149351947628 │ │ 679835412123694758548217936416723895892561374735489621287956143961342587354178269 │ └───────────────────────────────────────────────────────────────────────────────────┘ Run Time (s): real 10.209 user 9.331371 sys 0.000000计算成功速度不算太快可能是算法过于简单原因。李艳红先生将上述测试文档输入AIAI自动找到了问题并且修复了顺便还升级了数独算法用新的sudoku.lua重新编译一版sudoku_solve_opt函数速度是上一版本的100倍。testluaudf D SELECT * FROM luajit_module(mode : compile, sql_name : sudoku_solve_opt, source : local s dofile(./sudoku.lua) return function(x) return s.solve(x) end); ┌─────────┬─────────┬─────────┬─────────┬─────────┬──────────────────┐ │ ok │ mode │ phase │ message │ detail │ sql_name │ │ boolean │ varchar │ varchar │ varchar │ varchar │ varchar │ ├─────────┼─────────┼─────────┼─────────┼─────────┼──────────────────┤ │ true │ compile │ compile │ OK │ │ sudoku_solve_opt │ └─────────┴─────────┴─────────┴─────────┴─────────┴──────────────────┘ testluaudf D with a(i) as(select * from read_csv(sudoku17.txt) limit 3)select luajit_s(sudoku_solve_opt,i)from a; ┌───────────────────────────────────────────────────────────────────────────────────┐ │ luajit_s(sudoku_solve_opt, i) │ │ varchar │ ├───────────────────────────────────────────────────────────────────────────────────┤ │ 793684512486512937125973846932751684578246391641398725319465278857129463264837159 │ │ 673894512912735486845612973798261354526473891134589267469128735287356149351947628 │ │ 679835412123694758548217936416723895892561374735489621287956143961342587354178269 │ └───────────────────────────────────────────────────────────────────────────────────┘ testluaudf D .timer on testluaudf D with a(i) as(from read_csv(sudoku17.txt) limit 3)select max(luajit_s(sudoku_solve_opt,i))from a; ┌───────────────────────────────────────────────────────────────────────────────────┐ │ max(luajit_s(sudoku_solve_opt, i)) │ │ varchar │ ├───────────────────────────────────────────────────────────────────────────────────┤ │ 793684512486512937125973846932751684578246391641398725319465278857129463264837159 │ └───────────────────────────────────────────────────────────────────────────────────┘ Run Time (s): real 0.071 user 0.015625 sys 0.000000 testluaudf D with a(i) as(from read_csv(sudoku17.txt) limit 300)select max(luajit_s(sudoku_solve_opt,i))from a; ┌───────────────────────────────────────────────────────────────────────────────────┐ │ max(luajit_s(sudoku_solve_opt, i)) │ │ varchar │ ├───────────────────────────────────────────────────────────────────────────────────┤ │ 986735124143298576275614893459183762821467359637529481592371648364852917718946235 │ └───────────────────────────────────────────────────────────────────────────────────┘ Run Time (s): real 5.289 user 5.234375 sys 0.031250又及上个版本还存在lua自定义函数不能持久化的问题现在也解决了。到https://github.com/alitrack/duckdb-luajit/releases/tag/v0.32 下载离线版插件。强制安装并装载。将内存数据库保存到物理数据库文件再次打开此文件load luajit;后原来编译的lua自定义函数直接能用。C:\dduckdb155 -unsigned DuckDB v1.5.5 (Variegata) Enter .help for usage hints. memory D force install C:\Users\lt\Downloads\luajit.duckdb_extension; memory D from duckdb_extensions(); ┌──────────────────┬─────────┬───────────┬───┬───────────────────┬───────────────────┬─────────────────────────────────┐ │ extension_name │ loaded │ installed │ … │ extension_version │ install_mode │ installed_from │ │ varchar │ boolean │ boolean │ … │ varchar │ varchar │ varchar │ ├──────────────────┼─────────┼───────────┼───┼───────────────────┼───────────────────┼─────────────────────────────────┤ │ luajit │ false │ true │ … │ v0.32 │ CUSTOM_PATH │ C:\Users\lt\Downloads\luajit.d… │ memory D load luajit; memory D SELECT * FROM luajit_module(mode : compile, sql_name : sudoku_solve, source : local s dofile(duckdb-luajit-libs-main/libs/mcp/sudoku.lua) return function(x) return s.solve(x) end); ┌─────────┬─────────┬─────────┬─────────┬─────────┬──────────────┐ │ ok │ mode │ phase │ message │ detail │ sql_name │ │ boolean │ varchar │ varchar │ varchar │ varchar │ varchar │ ├─────────┼─────────┼─────────┼─────────┼─────────┼──────────────┤ │ true │ compile │ compile │ OK │ │ sudoku_solve │ └─────────┴─────────┴─────────┴─────────┴─────────┴──────────────┘ memory D SELECT luajit_s(sudoku_solve, 000001002000020030004500600007600050080090006100005800001004000070900003400030020) AS r; ┌───────────────────────────────────────────────────────────────────────────────────┐ │ r │ │ varchar │ ├───────────────────────────────────────────────────────────────────────────────────┤ │ 359461782716829534824573619947682351583197246162345897631254978275918463498736125 │ └───────────────────────────────────────────────────────────────────────────────────┘ memory D ATTACH lua032.db; memory D COPY FROM DATABASE memory to lua032; memory D .exit C:\dduckdb155 lua032.db -unsigned DuckDB v1.5.5 (Variegata) Enter .help for usage hints. lua032 D load luajit; lua032 D SELECT luajit_s(sudoku_solve, 000001002000020030004500600007600050080090006100005800001004000070900003400030020) AS r; ┌───────────────────────────────────────────────────────────────────────────────────┐ │ r │ │ varchar │ ├───────────────────────────────────────────────────────────────────────────────────┤ │ 359461782716829534824573619947682351583197246162345897631254978275918463498736125 │ └───────────────────────────────────────────────────────────────────────────────────┘