JSQLParser能否区分SELECT查询中的视图、函数与表?含调用场景验证
Absolutely, JSQLParser has the capability to distinguish between tables, views, and functions in SELECT statements—though there are a few nuances to how it handles each case, especially with the two function invocation styles you mentioned. Let’s break this down:
核心区分逻辑
JSQLParser parses SQL into an Abstract Syntax Tree (AST), where different database objects map to distinct node types. Here’s how it handles each object:
Tables vs. Views
From a syntax perspective, views and regular tables are written identically (e.g., SELECT * FROM my_view looks no different from SELECT * FROM my_table). Because of this, JSQLParser will parse both as Table nodes. To actually tell them apart, you’ll need to pair JSQLParser’s syntax parsing with database metadata checks (like querying information_schema.views in PostgreSQL) — JSQLParser itself only handles syntax, not database-specific metadata.
Function Recognition
Both of your example function calls are correctly identified as function invocations, though they map to different AST nodes based on their position in the query:
SELECT * FROM public.new(10);
Here,public.new(10)acts as a data source in the FROM clause. JSQLParser parses this as aTableFunctionnode, which wraps aFunctionCallsub-node. You can extract details like the function’s schema (public), name (new), and parameters (10) by accessing this node.SELECT public.new(10);
In this case, the function call is an expression in the SELECT list. JSQLParser directly parses this as aFunctionCallnode. Again, you can pull out all relevant details: schema, function name, and parameters.
Quick Example (Pseudocode)
To identify these objects programmatically, you can use JSQLParser’s Visitor pattern to traverse the AST:
// Parse the first query Select select = (Select) CCJSqlParserUtil.parse("select * from public.new(10);"); select.getSelectBody().accept(new SelectVisitorAdapter() { @Override public void visit(TableFunction tableFunction) { FunctionCall func = tableFunction.getFunctionCall(); System.out.println("Table function detected: " + func.getSchemaName() + "." + func.getName()); // Access parameters func.getParameters().forEach(param -> System.out.println("Parameter: " + param)); } }); // Parse the second query Select select2 = (Select) CCJSqlParserUtil.parse("select public.new(10);"); select2.getSelectBody().accept(new SelectVisitorAdapter() { @Override public void visit(SelectExpressionItem item) { if (item.getExpression() instanceof FunctionCall) { FunctionCall func = (FunctionCall) item.getExpression(); System.out.println("Function call detected: " + func.getSchemaName() + "." + func.getName()); } } });
Summary
- Tables and views can’t be distinguished by JSQLParser alone (syntax is identical), but you can pair it with database metadata checks to tell them apart.
- Both of your function invocation styles are correctly recognized, mapping to
TableFunction(when in FROM) andFunctionCall(when in SELECT list) nodes, with full access to function details.
内容的提问来源于stack exchange,提问作者girijanandan nucha

