-
Notifications
You must be signed in to change notification settings - Fork 497
/
SelectQueryable.kt
65 lines (59 loc) · 2.58 KB
/
SelectQueryable.kt
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
package app.cash.sqldelight.dialect.api
import com.alecstrong.sql.psi.core.psi.NamedElement
import com.alecstrong.sql.psi.core.psi.QueryElement.QueryColumn
import com.alecstrong.sql.psi.core.psi.Queryable
import com.alecstrong.sql.psi.core.psi.SqlAnnotatedElement
import com.alecstrong.sql.psi.core.psi.SqlCompoundSelectStmt
import com.alecstrong.sql.psi.core.psi.SqlCreateViewStmt
import com.alecstrong.sql.psi.core.psi.SqlCteTableName
import com.alecstrong.sql.psi.core.psi.SqlViewName
import com.intellij.psi.util.PsiTreeUtil
import com.intellij.psi.util.parentOfType
class SelectQueryable(
override val select: SqlCompoundSelectStmt,
override var statement: SqlAnnotatedElement = select,
) : QueryWithResults {
/**
* If this query is a pure select from a table (virtual or otherwise), this returns the LazyQuery
* which points to that table (Pure meaning it has exactly the same columns in the same order).
*/
override val pureTable: NamedElement? by lazy {
fun List<QueryColumn>.flattenCompounded(): List<QueryColumn> {
return map { column ->
if (column.compounded.none { it.element != column.element || it.nullable != column.nullable }) {
column.copy(compounded = emptyList())
} else {
column
}
}
}
val pureColumns = select.queryExposed().singleOrNull()?.columns?.flattenCompounded()
// First check to see if its just the table we're observing directly.
val tablesSelected = select.selectStmtList.flatMap {
it.joinClause?.tableOrSubqueryList?.mapNotNull { tableOrSubquery ->
val resolvedTable = tableOrSubquery.tableName?.reference?.resolve() ?: return@mapNotNull null
PsiTreeUtil.getParentOfType(resolvedTable, Queryable::class.java)?.tableExposed()
}.orEmpty()
}
tablesSelected.forEach {
if (it.query.columns.flattenCompounded() == pureColumns) {
val table = it.query.table
if (table is SqlViewName) {
// check, if this view uses exactly 1 pure table and use this table, if found.
val createViewStmt = table.nameIdentifier?.parentOfType<SqlCreateViewStmt>()?.compoundSelectStmt
if (createViewStmt != null) {
val foundPureTable = SelectQueryable(createViewStmt).pureTable
if (foundPureTable != null) {
return@lazy foundPureTable
}
}
}
return@lazy it.tableName
}
}
return@lazy select.tablesAvailable(select).firstOrNull {
(it.tableName.parent !is SqlCteTableName) &&
it.query.columns.flattenCompounded() == pureColumns
}?.tableName
}
}