test: cover SequenceTest and run

This commit is contained in:
dualfroz committed 2026-09-09 23:21:47 +02:00
1 parent 9e44181f8f
commit d08db6f834
1 file changed
+162
+162
View File
@@ -0,0 +1,162 @@
package kestrel
import kestrel.catalog.Catalog
import kestrel.engine.Executor
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
class SequenceTest {
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)
@Test
fun nextvalStartsAtOneAndIncrementsByOneByDefault() {
run("CREATE SEQUENCE seq")
run("CREATE TABLE t (id INTEGER)")
run("INSERT INTO t VALUES (NEXTVAL('seq')), (NEXTVAL('seq')), (NEXTVAL('seq'))")
assertEquals(listOf(listOf(int(1)), listOf(int(2)), listOf(int(3))), select("SELECT id FROM t ORDER BY id").rows)
}
@Test
fun createSequenceOptionsAreHonored() {
run("CREATE SEQUENCE seq START WITH 100 INCREMENT BY 10")
run("CREATE TABLE t (id INTEGER)")
run("INSERT INTO t VALUES (NEXTVAL('seq')), (NEXTVAL('seq'))")
assertEquals(listOf(listOf(int(100)), listOf(int(110))), select("SELECT id FROM t ORDER BY id").rows)
}
@Test
fun descendingSequenceDefaultsToMaxvalueAndCountsDown() {
run("CREATE SEQUENCE seq INCREMENT BY -1")
run("CREATE TABLE t (id INTEGER)")
run("INSERT INTO t VALUES (NEXTVAL('seq')), (NEXTVAL('seq'))")
assertEquals(listOf(listOf(int(-2)), listOf(int(-1))), select("SELECT id FROM t ORDER BY id").rows)
}
@Test
fun exhaustedAscendingSequenceWithoutCycleThrows() {
run("CREATE SEQUENCE seq MAXVALUE 2")
run("CREATE TABLE t (id INTEGER)")
run("INSERT INTO t VALUES (NEXTVAL('seq'))")
run("INSERT INTO t VALUES (NEXTVAL('seq'))")
assertFailsWith<KestrelException> { run("INSERT INTO t VALUES (NEXTVAL('seq'))") }
}
@Test
fun cyclingAscendingSequenceWrapsToMinvalue() {
run("CREATE SEQUENCE seq MAXVALUE 2 CYCLE")
run("CREATE TABLE t (id INTEGER)")
run("INSERT INTO t VALUES (NEXTVAL('seq')), (NEXTVAL('seq')), (NEXTVAL('seq'))")
assertEquals(listOf(listOf(int(1)), listOf(int(2)), listOf(int(1))), select("SELECT id FROM t").rows)
}
@Test
fun dropSequenceRemovesItAndFurtherNextvalFails() {
run("CREATE SEQUENCE seq")
run("DROP SEQUENCE seq")
run("CREATE TABLE t (id INTEGER)")
assertFailsWith<KestrelException> { run("INSERT INTO t VALUES (NEXTVAL('seq'))") }
}
@Test
fun duplicateCreateSequenceFails() {
run("CREATE SEQUENCE seq")
assertFailsWith<KestrelException> { run("CREATE SEQUENCE seq") }
}
@Test
fun droppingAnUnknownSequenceFails() {
assertFailsWith<KestrelException> { run("DROP SEQUENCE nope") }
}
@Test
fun alterSequenceRestartWithResetsPosition() {
run("CREATE SEQUENCE seq")
run("CREATE TABLE t (id INTEGER)")
run("INSERT INTO t VALUES (NEXTVAL('seq')), (NEXTVAL('seq'))")
run("ALTER SEQUENCE seq RESTART WITH 50")
run("INSERT INTO t VALUES (NEXTVAL('seq'))")
assertEquals(listOf(listOf(int(1)), listOf(int(2)), listOf(int(50))), select("SELECT id FROM t ORDER BY id").rows)
}
@Test
fun bareRestartResetsToOriginalStartValue() {
run("CREATE SEQUENCE seq START WITH 5")
run("CREATE TABLE t (id INTEGER)")
run("INSERT INTO t VALUES (NEXTVAL('seq')), (NEXTVAL('seq'))")
run("ALTER SEQUENCE seq RESTART")
run("INSERT INTO t VALUES (NEXTVAL('seq'))")
assertEquals(listOf(listOf(int(5)), listOf(int(5)), listOf(int(6))), select("SELECT id FROM t ORDER BY id").rows)
}
@Test
fun alterSequenceIncrementByWithoutRestartPreservesCurrentPosition() {
run("CREATE SEQUENCE seq")
run("CREATE TABLE t (id INTEGER)")
run("INSERT INTO t VALUES (NEXTVAL('seq'))")
run("ALTER SEQUENCE seq INCREMENT BY 100")
run("INSERT INTO t VALUES (NEXTVAL('seq'))")
assertEquals(listOf(listOf(int(1)), listOf(int(101))), select("SELECT id FROM t ORDER BY id").rows)
}
@Test
fun alterSequenceRestartValueOutOfNewBoundsFails() {
run("CREATE SEQUENCE seq MAXVALUE 10")
assertFailsWith<KestrelException> { run("ALTER SEQUENCE seq RESTART WITH 20") }
}
@Test
fun alteringAnUnknownSequenceFails() {
assertFailsWith<KestrelException> { run("ALTER SEQUENCE nope INCREMENT BY 2") }
}
@Test
fun currvalReturnsLastNextvalInThisSession() {
run("CREATE SEQUENCE seq")
run("CREATE TABLE t (id INTEGER, again INTEGER)")
run("INSERT INTO t VALUES (NEXTVAL('seq'), CURRVAL('seq'))")
assertEquals(listOf(listOf(int(1), int(1))), select("SELECT id, again FROM t").rows)
}
@Test
fun currvalBeforeAnyNextvalInThisSessionFails() {
run("CREATE SEQUENCE seq")
run("CREATE TABLE t (id INTEGER)")
assertFailsWith<KestrelException> { run("INSERT INTO t VALUES (CURRVAL('seq'))") }
}
@Test
fun alterSequenceInvalidatesRememberedCurrvalForThatSession() {
run("CREATE SEQUENCE seq")
run("CREATE TABLE t (id INTEGER)")
run("INSERT INTO t VALUES (NEXTVAL('seq'))")
run("ALTER SEQUENCE seq INCREMENT BY 1")
assertFailsWith<KestrelException> { run("INSERT INTO t VALUES (CURRVAL('seq'))") }
}
@Test
fun rollbackDoesNotUndoANextvalAdvance() {
run("CREATE SEQUENCE seq")
run("CREATE TABLE t (id INTEGER)")
run("BEGIN")
run("INSERT INTO t VALUES (NEXTVAL('seq'))")
run("ROLLBACK")
run("INSERT INTO t VALUES (NEXTVAL('seq'))")
// The rolled-back row never landed, but NEXTVAL's advance to 1 survives - the surviving
// insert gets 2, not a reused 1.
assertEquals(listOf(listOf(int(2))), select("SELECT id FROM t").rows)
}