test: cover ExpressionLanguageTest and run
This commit is contained in:
1 parent
90139e824b
commit
f3a0059bc3
1 file changed
+158
@@ -0,0 +1,158 @@
|
|||||||
|
package kestrel
|
||||||
|
|
||||||
|
import java.math.BigDecimal
|
||||||
|
import java.time.LocalDate
|
||||||
|
import kestrel.catalog.Catalog
|
||||||
|
import kestrel.engine.Executor
|
||||||
|
import kestrel.engine.ExplainResult
|
||||||
|
import kestrel.engine.SelectResult
|
||||||
|
import kestrel.engine.StatementResult
|
||||||
|
import kestrel.sql.lexer.Lexer
|
||||||
|
import kestrel.sql.parser.Parser
|
||||||
|
import kestrel.storage.Value
|
||||||
|
import kotlin.test.Test
|
||||||
|
import kotlin.test.assertEquals
|
||||||
|
import kotlin.test.assertFailsWith
|
||||||
|
import kotlin.test.assertTrue
|
||||||
|
|
||||||
|
class ExpressionLanguageTest {
|
||||||
|
private val catalog = Catalog()
|
||||||
|
private val executor = Executor(catalog)
|
||||||
|
|
||||||
|
private fun run(sql: String): List<StatementResult> =
|
||||||
|
Parser(Lexer(sql).tokenize()).parseProgram().map { executor.execute(it) }
|
||||||
|
|
||||||
|
private fun select(sql: String): SelectResult = run(sql).single() as SelectResult
|
||||||
|
|
||||||
|
private fun int(value: Long) = Value.IntegerValue(value)
|
||||||
|
private fun text(value: String) = Value.TextValue(value)
|
||||||
|
|
||||||
|
private fun seedUsers() {
|
||||||
|
run("CREATE TABLE users (id INTEGER PRIMARY KEY, name TEXT NOT NULL, age INTEGER, bio TEXT)")
|
||||||
|
run(
|
||||||
|
"INSERT INTO users VALUES " +
|
||||||
|
"(1, 'ada', 36, 'mathematician'), (2, 'linus', 54, NULL), " +
|
||||||
|
"(3, 'grace', 85, 'rear admiral')"
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun scalarFunctionInProjection() {
|
||||||
|
seedUsers()
|
||||||
|
val result = select("SELECT UPPER(name) FROM users ORDER BY id ASC")
|
||||||
|
assertEquals(listOf("upper"), result.columns)
|
||||||
|
assertEquals(listOf(text("ADA"), text("LINUS"), text("GRACE")), result.rows.map { it[0] })
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun scalarFunctionInWhereClause() {
|
||||||
|
seedUsers()
|
||||||
|
val result = select("SELECT name FROM users WHERE LENGTH(name) > 4 ORDER BY name ASC")
|
||||||
|
assertEquals(listOf(listOf(text("grace")), listOf(text("linus"))), result.rows)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun scalarFunctionUsableInUpdateAssignment() {
|
||||||
|
seedUsers()
|
||||||
|
run("UPDATE users SET name = UPPER(name) WHERE id = 1")
|
||||||
|
val result = select("SELECT name FROM users WHERE id = 1")
|
||||||
|
assertEquals(listOf(listOf(text("ADA"))), result.rows)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun nestedFunctionCalls() {
|
||||||
|
seedUsers()
|
||||||
|
val result = select("SELECT SUBSTR(UPPER(name), 1, 1) FROM users WHERE id = 1")
|
||||||
|
assertEquals(listOf(listOf(text("A"))), result.rows)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun isNullFiltersRowsWithMissingValues() {
|
||||||
|
seedUsers()
|
||||||
|
val result = select("SELECT name FROM users WHERE bio IS NULL")
|
||||||
|
assertEquals(listOf(listOf(text("linus"))), result.rows)
|
||||||
|
val negated = select("SELECT COUNT(*) FROM users WHERE bio IS NOT NULL")
|
||||||
|
assertEquals(listOf(listOf(int(2))), negated.rows)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun inClauseMatchesAgainstLiteralSet() {
|
||||||
|
seedUsers()
|
||||||
|
val result = select("SELECT name FROM users WHERE age IN (36, 85) ORDER BY age ASC")
|
||||||
|
assertEquals(listOf(listOf(text("ada")), listOf(text("grace"))), result.rows)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun notInExcludesMatchingRows() {
|
||||||
|
seedUsers()
|
||||||
|
val result = select("SELECT name FROM users WHERE age NOT IN (36, 85)")
|
||||||
|
assertEquals(listOf(listOf(text("linus"))), result.rows)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun betweenSelectsInclusiveRange() {
|
||||||
|
seedUsers()
|
||||||
|
val result = select("SELECT name FROM users WHERE age BETWEEN 40 AND 90 ORDER BY age ASC")
|
||||||
|
assertEquals(listOf(listOf(text("linus")), listOf(text("grace"))), result.rows)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun likeMatchesWildcardPattern() {
|
||||||
|
seedUsers()
|
||||||
|
val result = select("SELECT name FROM users WHERE bio LIKE '%admiral' ")
|
||||||
|
assertEquals(listOf(listOf(text("grace"))), result.rows)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun caseExpressionInProjection() {
|
||||||
|
seedUsers()
|
||||||
|
val result = select(
|
||||||
|
"SELECT name, CASE WHEN age < 50 THEN 'young' WHEN age < 80 THEN 'mid' ELSE 'senior' END " +
|
||||||
|
"FROM users ORDER BY id ASC"
|
||||||
|
)
|
||||||
|
assertEquals(
|
||||||
|
listOf(
|
||||||
|
listOf(text("ada"), text("young")),
|
||||||
|
listOf(text("linus"), text("mid")),
|
||||||
|
listOf(text("grace"), text("senior"))
|
||||||
|
),
|
||||||
|
result.rows
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun caseExpressionUsableInWhereClause() {
|
||||||
|
seedUsers()
|
||||||
|
val result = select(
|
||||||
|
"SELECT name FROM users WHERE CASE WHEN age > 40 THEN TRUE ELSE FALSE END ORDER BY name ASC"
|
||||||
|
)
|
||||||
|
assertEquals(listOf(listOf(text("grace")), listOf(text("linus"))), result.rows)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun combiningPredicatesWithLogicalOperators() {
|
||||||
|
seedUsers()
|
||||||
|
val result = select(
|
||||||
|
"SELECT name FROM users WHERE age BETWEEN 30 AND 60 AND name LIKE 'a%'"
|
||||||
|
)
|
||||||
|
assertEquals(listOf(listOf(text("ada"))), result.rows)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun aggregateOfScalarFunctionResult() {
|
||||||
|
seedUsers()
|
||||||
|
val result = select("SELECT SUM(LENGTH(name)) FROM users")
|
||||||
|
assertEquals(listOf(listOf(int(3 + 5 + 5))), result.rows)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun groupByWithFunctionOnGroupedColumn() {
|
||||||
|
run("CREATE TABLE t (category TEXT, amount INTEGER)")
|
||||||
|
run("INSERT INTO t VALUES ('Eng', 10), ('eng', 20), ('Ops', 5)")
|
||||||
|
val result = select("SELECT LOWER(category), SUM(amount) FROM t GROUP BY LOWER(category) ORDER BY LOWER(category) ASC")
|
||||||
|
assertEquals(
|
||||||
|
listOf(listOf(text("eng"), int(30)), listOf(text("ops"), int(5))),
|
||||||
|
result.rows
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
Reference in new issue
Block a user