test: cover conflictDoUpdateEnforcesCheckConstraintsOnTheResultingRow
This commit is contained in:
1 parent
0f54d1fe15
commit
4682431a80
1 file changed
+72
@@ -160,3 +160,75 @@ class UpsertTest {
|
||||
assertTrue(error.message!!.contains("NOT NULL"), error.message!!)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun conflictDoUpdateEnforcesCheckConstraintsOnTheResultingRow() {
|
||||
run(
|
||||
"CREATE TABLE accounts (id INTEGER PRIMARY KEY, balance INTEGER CHECK (balance >= 0))"
|
||||
)
|
||||
run("INSERT INTO accounts VALUES (1, 100)")
|
||||
val error = assertFailsWith<KestrelException> {
|
||||
run("INSERT INTO accounts VALUES (1, 100) ON CONFLICT (id) DO UPDATE SET balance = -5")
|
||||
}
|
||||
assertTrue(error.message!!.contains("CHECK constraint"), error.message!!)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun conflictDoUpdateRunsForeignKeyValidationOnTheUpdatedRow() {
|
||||
run("CREATE TABLE departments (id INTEGER PRIMARY KEY)")
|
||||
run("INSERT INTO departments VALUES (1)")
|
||||
run(
|
||||
"CREATE TABLE employees (id INTEGER PRIMARY KEY, dept INTEGER REFERENCES departments(id))"
|
||||
)
|
||||
run("INSERT INTO employees VALUES (1, 1)")
|
||||
val error = assertFailsWith<KestrelException> {
|
||||
run("INSERT INTO employees VALUES (1, 1) ON CONFLICT (id) DO UPDATE SET dept = 999")
|
||||
}
|
||||
assertTrue(error.message!!.contains("FOREIGN KEY"), error.message!!)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun conflictDoUpdateCascadesToChildTablesWhenTheReferencedKeyChanges() {
|
||||
run("CREATE TABLE departments (id INTEGER PRIMARY KEY)")
|
||||
run("INSERT INTO departments VALUES (1)")
|
||||
run(
|
||||
"CREATE TABLE employees (id INTEGER PRIMARY KEY, dept INTEGER REFERENCES departments(id) ON UPDATE CASCADE)"
|
||||
)
|
||||
run("INSERT INTO employees VALUES (1, 1)")
|
||||
insertCount("INSERT INTO departments VALUES (1) ON CONFLICT (id) DO UPDATE SET id = 2")
|
||||
assertEquals(Value.IntegerValue(2), select("SELECT dept FROM employees WHERE id = 1").rows[0][0])
|
||||
}
|
||||
|
||||
@Test
|
||||
fun compositePrimaryKeyConflictTargetIsRecognised() {
|
||||
run(
|
||||
"CREATE TABLE grades (student INTEGER, course INTEGER, score INTEGER, PRIMARY KEY (student, course))"
|
||||
)
|
||||
run("INSERT INTO grades VALUES (1, 10, 50)")
|
||||
val count = insertCount(
|
||||
"INSERT INTO grades VALUES (1, 10, 90) ON CONFLICT (student, course) DO UPDATE SET score = excluded.score"
|
||||
)
|
||||
assertEquals(1, count)
|
||||
assertEquals(Value.IntegerValue(90), select("SELECT score FROM grades WHERE student = 1 AND course = 10").rows[0][0])
|
||||
}
|
||||
|
||||
@Test
|
||||
fun conflictDoUpdateDefaultKeywordFallsBackToColumnDefault() {
|
||||
run("CREATE TABLE t (id INTEGER PRIMARY KEY, note TEXT DEFAULT 'fresh')")
|
||||
run("INSERT INTO t VALUES (1, 'stale')")
|
||||
insertCount("INSERT INTO t VALUES (1, 'stale') ON CONFLICT (id) DO UPDATE SET note = DEFAULT")
|
||||
assertEquals("fresh", (select("SELECT note FROM t WHERE id = 1").rows[0][0] as Value.TextValue).value)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun tableStateAfterAConflictResolutionStillDumpsAndReplaysCleanly() {
|
||||
seed()
|
||||
run("INSERT INTO accounts VALUES (2, 'linus', 200) ON CONFLICT (id) DO UPDATE SET balance = excluded.balance")
|
||||
val dumped = kestrel.persistence.SqlWriter.dump(catalog)
|
||||
val replayCatalog = Catalog()
|
||||
val replayExecutor = Executor(replayCatalog)
|
||||
Parser(Lexer(dumped).tokenize()).parseProgram().forEach { replayExecutor.execute(it) }
|
||||
val replaySelect = Parser(Lexer("SELECT * FROM accounts").tokenize()).parseProgram()
|
||||
.map { replayExecutor.execute(it) }.single() as SelectResult
|
||||
assertEquals(2, replaySelect.rows.size)
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user