用parser_tools插件来解析SQL语句
C:\d>duckdb140
DuckDB v1.4.0 (Andium) b8a06e4a22
Enter ".help" for usage hints.
Connected to a transient in-memory database.
Use ".open FILENAME" to reopen on a persistent database.
D INSTALL parser_tools FROM community;
100% ▕██████████████████████████████████████▏ (00:00:02.45 elapsed)
D LOAD parser_tools;
D SELECT * FROM parse_tables('SELECT * FROM my_table');
┌─────────┬──────────┬─────────┐
│ schema │ table │ context │
│ varchar │ varchar │ varchar │
├─────────┼──────────┼─────────┤
│ main │ my_table │ from │
└─────────┴──────────┴─────────┘
D SELECT * FROM parse_tables($$
路 WITH recent_users AS (SELECT * FROM users WHERE created_at > now() - INTERVAL '7 days')
路 SELECT * FROM recent_users r JOIN logins l ON r.id = l.user_id
路 $$);
┌─────────┬──────────────┬────────────┐
│ schema │ table │ context │
│ varchar │ varchar │ varchar │
├─────────┼──────────────┼────────────┤
│ │ recent_users │ cte │
│ main │ users │ from │
│ main │ recent_users │ from_cte │
│ main │ logins │ join_right │
└─────────┴──────────────┴────────────┘
D SELECT parse_table_names('SELECT * FROM orders JOIN customers ON orders.customer_id = customers.id');
┌───────────────────────────────────────────────────────────────────────────────────────────────┐
│ parse_table_names('SELECT * FROM orders JOIN customers ON orders.customer_id = customers.id') │
│ varchar[] │
├───────────────────────────────────────────────────────────────────────────────────────────────┤
│ [orders, customers] │
└───────────────────────────────────────────────────────────────────────────────────────────────┘
D SELECT parse_table_names(query) AS tables FROM 'user_queries.csv';
IO Error:
No files found that match the pattern "user_queries.csv"
D SELECT parse_tables('SELECT * FROM products p JOIN inventory i ON p.sku = i.sku');
┌─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐
│ parse_tables('SELECT * FROM products p JOIN inventory i ON p.sku = i.sku') │
│ struct("schema" varchar, "table" varchar, context varchar)[] │
├─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┤
│ [{'schema': main, 'table': products, 'context': from}, {'schema': main, 'table': inventory, 'context': join_right}] │
└─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘
D SELECT query, is_parsable(query) AS valid
路 FROM (VALUES
路 ('SELECT * FROM good_table'),
路 ('BAD SQL SELECT *'),
路 ('WITH cte AS (SELECT 1) SELECT * FROM cte')
路 ) AS t(query);
┌──────────────────────────────────────────┬─────────┐
│ query │ valid │
│ varchar │ boolean │
├──────────────────────────────────────────┼─────────┤
│ SELECT * FROM good_table │ true │
│ BAD SQL SELECT * │ false │
│ WITH cte AS (SELECT 1) SELECT * FROM cte │ true │
└──────────────────────────────────────────┴─────────┘
D SELECT * FROM parse_where('SELECT * FROM MyTable WHERE time > 1 AND time < 100');
┌────────────────┬────────────┬─────────┐
│ condition │ table_name │ context │
│ varchar │ varchar │ varchar │
├────────────────┼────────────┼─────────┤
│ ("time" > 1) │ MyTable │ WHERE │
│ ("time" < 100) │ MyTable │ WHERE │
└────────────────┴────────────┴─────────┘
D SELECT * FROM parse_where_detailed('SELECT * FROM MyTable WHERE time > 1 AND time < 100');
┌─────────────┬───────────────┬─────────┬────────────┬─────────┐
│ column_name │ operator_type │ value │ table_name │ context │
│ varchar │ varchar │ varchar │ varchar │ varchar │
├─────────────┼───────────────┼─────────┼────────────┼─────────┤
│ time │ > │ 1 │ MyTable │ WHERE │
│ time │ < │ 100 │ MyTable │ WHERE │
└─────────────┴───────────────┴─────────┴────────────┴─────────┘
D SELECT * FROM parse_where('SELECT * FROM MyTable WHERE time BETWEEN 1 AND 100');
┌────────────────────────────┬────────────┬─────────┐
│ condition │ table_name │ context │
│ varchar │ varchar │ varchar │
├────────────────────────────┼────────────┼─────────┤
│ ("time" BETWEEN 1 AND 100) │ MyTable │ WHERE │
└────────────────────────────┴────────────┴─────────┘
D SELECT * FROM parse_where_detailed('SELECT * FROM MyTable WHERE time BETWEEN 1 AND 100');
┌─────────────┬───────────────┬─────────┬────────────┬─────────┐
│ column_name │ operator_type │ value │ table_name │ context │
│ varchar │ varchar │ varchar │ varchar │ varchar │
├─────────────┼───────────────┼─────────┼────────────┼─────────┤
│ time │ >= │ 1 │ MyTable │ WHERE │
│ time │ <= │ 100 │ MyTable │ WHERE │
└─────────────┴───────────────┴─────────┴────────────┴─────────┘
D SELECT * FROM parse_functions('SELECT upper(name), count(*) FROM users WHERE length(email) > 0');
┌───────────────┬─────────┬─────────┐
│ function_name │ schema │ context │
│ varchar │ varchar │ varchar │
├───────────────┼─────────┼─────────┤
│ upper │ main │ select │
│ count_star │ main │ select │
│ length │ main │ where │
└───────────────┴─────────┴─────────┘
D SELECT * from parse_statements('SELECT 42; INSERT INTO log VALUES (1); SELECT 43;') as statements;
┌──────────────────────────────┐
│ statement │
│ varchar │
├──────────────────────────────┤
│ SELECT 42 │
│ INSERT INTO log (VALUES (1)) │
│ SELECT 43 │
└──────────────────────────────┘
D SELECT num_statements('SELECT 1; SELECT 2; SELECT 3;');
┌─────────────────────────────────────────────────┐
│ num_statements('SELECT 1; SELECT 2; SELECT 3;') │
│ int64 │
├─────────────────────────────────────────────────┤
│ 3 │
└─────────────────────────────────────────────────┘
D SELECT * FROM parse_tables('PIVOT cities ON year USING sum(population);');
┌─────────┬─────────┬─────────┐
│ schema │ table │ context │
│ varchar │ varchar │ varchar │
├─────────┴─────────┴─────────┤
│ 0 rows │
└─────────────────────────────┘
D
根据存储库页面 https://github.com/zfarrell/duckdb_extension_parser_tools 介绍,这个实验性插件目前只能解析SELECT语句,所以PIVOT解析不出结果。