From 4f671d10430b446702bd0b5beea1ebd1c401a4b8 Mon Sep 17 00:00:00 2001 From: DualFroz Date: Wed, 9 Sep 2026 23:29:37 +0200 Subject: [PATCH] test: cover rollbackUndoesCreateSequence and rollbackUndoesDropSequence --- src/test/kotlin/kestrel/SequenceTest.kt | 142 ++++++++++++++++++++++++ 1 file changed, 142 insertions(+) diff --git a/src/test/kotlin/kestrel/SequenceTest.kt b/src/test/kotlin/kestrel/SequenceTest.kt index 6f7068c..70797fc 100644 --- a/src/test/kotlin/kestrel/SequenceTest.kt +++ b/src/test/kotlin/kestrel/SequenceTest.kt @@ -160,3 +160,145 @@ class SequenceTest { assertEquals(listOf(listOf(int(2))), select("SELECT id FROM t").rows) } + @Test + fun rollbackUndoesCreateSequence() { + run("BEGIN") + run("CREATE SEQUENCE seq") + run("ROLLBACK") + assertFailsWith { run("DROP SEQUENCE seq") } + } + + @Test + fun rollbackUndoesDropSequence() { + run("CREATE SEQUENCE seq") + run("BEGIN") + run("DROP SEQUENCE seq") + run("ROLLBACK") + run("CREATE TABLE t (id INTEGER)") + run("INSERT INTO t VALUES (NEXTVAL('seq'))") + assertEquals(listOf(listOf(int(1))), select("SELECT id FROM t").rows) + } + + @Test + fun rollbackUndoesAlterSequenceButNotTheNextvalAdvanceMadeBeforeIt() { + run("CREATE SEQUENCE seq") + run("CREATE TABLE t (id INTEGER)") + run("INSERT INTO t VALUES (NEXTVAL('seq'))") + run("BEGIN") + run("ALTER SEQUENCE seq INCREMENT BY 100") + run("ROLLBACK") + run("INSERT INTO t VALUES (NEXTVAL('seq'))") + assertEquals(listOf(listOf(int(1)), listOf(int(2))), select("SELECT id FROM t ORDER BY id").rows) + } + + @Test + fun nextvalAsColumnDefaultActsLikeAnAutoIncrement() { + run("CREATE SEQUENCE order_ids") + run("CREATE TABLE orders (id INTEGER PRIMARY KEY DEFAULT NEXTVAL('order_ids'), item TEXT)") + run("INSERT INTO orders (item) VALUES ('a'), ('b'), ('c')") + assertEquals( + listOf(listOf(int(1), Value.TextValue("a")), listOf(int(2), Value.TextValue("b")), listOf(int(3), Value.TextValue("c"))), + select("SELECT id, item FROM orders ORDER BY id").rows + ) + } + + @Test + fun createTableWithNextvalDefaultRequiresTheSequenceToAlreadyExist() { + assertFailsWith { + run("CREATE TABLE orders (id INTEGER DEFAULT NEXTVAL('nope'))") + } + } + + @Test + fun createTableDoesNotConsumeASequenceValueJustToValidateTheDefault() { + run("CREATE SEQUENCE seq") + run("CREATE TABLE orders (id INTEGER DEFAULT NEXTVAL('seq'))") + run("INSERT INTO orders (id) VALUES (DEFAULT)") + // If CREATE TABLE's own validation had already called NEXTVAL once, this would be 2. + assertEquals(listOf(listOf(int(1))), select("SELECT id FROM orders").rows) + } + + @Test + fun nextvalDefaultOnANonIntegerColumnFails() { + run("CREATE SEQUENCE seq") + assertFailsWith { + run("CREATE TABLE orders (id TEXT DEFAULT NEXTVAL('seq'))") + } + } + + @Test + fun currvalAsColumnDefaultIsRejected() { + run("CREATE SEQUENCE seq") + assertFailsWith { + run("CREATE TABLE orders (id INTEGER DEFAULT CURRVAL('seq'))") + } + } + + @Test + fun addColumnWithNextvalDefaultIsRejected() { + run("CREATE SEQUENCE seq") + run("CREATE TABLE t (id INTEGER)") + assertFailsWith { + run("ALTER TABLE t ADD COLUMN seq_id INTEGER DEFAULT NEXTVAL('seq')") + } + } + + @Test + fun nextvalIsUsableInUpdateSet() { + run("CREATE SEQUENCE seq") + run("CREATE TABLE t (id INTEGER)") + run("INSERT INTO t VALUES (NULL)") + run("UPDATE t SET id = NEXTVAL('seq')") + assertEquals(listOf(listOf(int(1))), select("SELECT id FROM t").rows) + } + + @Test + fun nextvalInAWhereClauseIsRejected() { + run("CREATE SEQUENCE seq") + run("CREATE TABLE t (id INTEGER)") + run("INSERT INTO t VALUES (1)") + assertFailsWith { run("UPDATE t SET id = 2 WHERE id = NEXTVAL('seq')") } + } + + @Test + fun nextvalInACheckConstraintIsRejectedAtCreateTableTime() { + run("CREATE SEQUENCE seq") + assertFailsWith { + run("CREATE TABLE t (id INTEGER CHECK (id = NEXTVAL('seq')))") + } + } + + @Test + fun nextvalInATriggerWhenClauseIsRejected() { + run("CREATE SEQUENCE seq") + run("CREATE TABLE t (id INTEGER)") + assertFailsWith { + run("CREATE TRIGGER trg BEFORE INSERT ON t FOR EACH ROW WHEN (NEXTVAL('seq') = 1) BEGIN DELETE FROM t; END") + } + } + + @Test + fun createSequenceMinvalueExceedingMaxvalueFails() { + assertFailsWith { run("CREATE SEQUENCE seq MINVALUE 10 MAXVALUE 5") } + } + + @Test + fun createSequenceIncrementByZeroFails() { + assertFailsWith { run("CREATE SEQUENCE seq INCREMENT BY 0") } + } + + @Test + fun createSequenceStartOutsideBoundsFails() { + assertFailsWith { run("CREATE SEQUENCE seq MINVALUE 10 MAXVALUE 20 START WITH 5") } + } + + @Test + fun noMinvalueAndNoMaxvalueOnAlterRecomputeTheDefaultBound() { + run("CREATE SEQUENCE seq MINVALUE 1 MAXVALUE 3") + run("ALTER SEQUENCE seq NO MAXVALUE") + run("CREATE TABLE t (id INTEGER)") + // Was capped at 3 before the ALTER; NO MAXVALUE lifts it back to the ascending default. + run("INSERT INTO t VALUES (NEXTVAL('seq')), (NEXTVAL('seq')), (NEXTVAL('seq')), (NEXTVAL('seq'))") + assertEquals(4, select("SELECT id FROM t").rows.size) + } +}