test: cover ExpressionLanguageTest and run

This commit is contained in:
dualfroz committed 2026-09-08 22:37:20 +02:00
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
)
}