1

我正在尝试从这里实现 sqlparser 并使用 gsqlparser 。jar 的来源是 Java,但我在 Scala 中实现了相同的。

下面是我的查询,其中包含一个连接条件。

 SELECT e.last_name AS name, e.commission_pct comm, e.salary * 12 "Annual Salary" FROM scott.employees AS e right join scott.companies as c on c.orgid = e.orgid and c.orgname = e.orgn WHERE e.salary > 1000 ORDER BY e.first_name, e.last_name

我能够解析查询以读取列的名称和别名、条件、表名(直接在查询中检查表名),如下所示。

val sqlParser = new TGSqlParser(EDbVendor.dbvsnowflake)
sqlParser.sqltext = "SELECT e.last_name AS name, e.commission_pct comm, e.salary * 12 \"Annual Salary\" FROM scott.employees AS e right join scott.companies as c on c.orgid = e.orgid and c.orgname = e.orgn WHERE e.salary > 1000 ORDER BY e.first_name, e.last_name"
val selectStmnt = sqlParser.sqltext
    println("Columns List:")
for(i <- 0 until selectStmnt.getResultColumnList.size()) {
  val resCol = selectStmnt.getResultColumnList.getResultColumn(i)
  println("Column: " + resCol.getExpr.toString + " Alias: " + resCol

.getAliasClause().toString)
    }

输出:

Columns List:
Column: e.last_name Alias: name
Column: e.commission_pct Alias: comm
Column: e.salary * 12 Alias: "Annual Salary"

我正在尝试解析连接条件并获取其中的详细信息

for(j <- 0 until selectStmnt.getJoins.size()) {
    println(selectStmnt.getJoins.getJoin(j).getTable)
}

这里的问题是查询中只有一个连接条件,因此返回的大小为 1。因此输出为scott.employees. 如果我这样做有点不同,如下所示getJoinItems

println("Parsing Join items")
for(j <- 0 until selectStmnt.getJoins.size()) {
    println(selectStmnt.getJoins.getJoin(j).getJoinItems)
}

我通过从连接条件中截断第一个表来获得输出,如下所示:

scott.companies as c on c.orgid = e.orgid and c.orgname = e.orgn

方法:getJoinItems() 返回一个列表:TJoinItemList我想遍历它。但即使它的大小也是 1。

println(selectStmnt.getJoins.getJoin(j).getJoinItems.size()) -> 1

我现在没有主意了。谁能让我知道如何解析查询的联接条件并获取联接内的表名?

4

1 回答 1

2

我无法访问 GSP 中的 Snowflake 方言,但我使用以下查询使用 Teradata 方言模仿了这种场景并创建了一个 sql 解析器。

SELECT e.last_name as name
FROM department d
RIGHT JOIN 
trimmed_employee e
ON d.dept_id = e.emp_id
WHERE e.salary > 1000
ORDER BY e.first_name

这是获取两个表的 Groovy 代码departmenttrimmed_employee. 它归结为迭代每个连接,并在这样做的同时收集当前连接的项目(joinItems),curJoin.joinItems仅当它不为空时才使用。

stmt.joins.asList().collect { curJoin -> 
  [curJoin.table] + (curJoin?.joinItems?.asList()?.collect { joinItems ->  joinItems.table } ?: [])
}.flatten()

结果:

department
trimmed_employee

对于您在我的案例中提到的这个简单的 sql,以下代码也适用。

stmt.tables.asList()
于 2021-12-24T14:44:38.547 回答