test(sql): cover onConflictOnATemporaryTableIsRejected
This commit is contained in:
1 parent
0b14ca4caa
commit
b50f24109e
1 file changed
+129
@@ -156,3 +156,132 @@ class DiskExecutorTemporaryTableTest {
|
||||
db.run("INSERT INTO scratch (id) VALUES (1)")
|
||||
assertEquals(listOf(int(1), int(10), int(20)), db.select("SELECT * FROM scratch").rows.single())
|
||||
|
||||
assertFailsWith<KestrelException> { db.run("INSERT INTO scratch (id, doubled) VALUES (2, 99)") }
|
||||
}
|
||||
|
||||
@Test
|
||||
fun onConflictOnATemporaryTableIsRejected() {
|
||||
val db = newDatabase()
|
||||
db.run("CREATE TEMP TABLE scratch (id INTEGER PRIMARY KEY)")
|
||||
db.run("INSERT INTO scratch VALUES (1)")
|
||||
assertFailsWith<KestrelException> { db.run("INSERT INTO scratch VALUES (1) ON CONFLICT (id) DO NOTHING") }
|
||||
}
|
||||
|
||||
@Test
|
||||
fun foreignKeyOnATemporaryTableIsRejectedAtCreateTime() {
|
||||
val db = newDatabase()
|
||||
db.run("CREATE TABLE parent (id INTEGER PRIMARY KEY)")
|
||||
assertFailsWith<KestrelException> {
|
||||
db.run("CREATE TEMP TABLE child (id INTEGER, parent_id INTEGER REFERENCES parent(id))")
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun createIndexAndCreateTriggerOnATemporaryTableAreRejected() {
|
||||
val db = newDatabase()
|
||||
db.run("CREATE TEMP TABLE scratch (id INTEGER)")
|
||||
assertFailsWith<KestrelException> { db.run("CREATE INDEX scratch_idx ON scratch(id)") }
|
||||
assertFailsWith<KestrelException> {
|
||||
db.run("CREATE TRIGGER scratch_trg AFTER INSERT ON scratch FOR EACH ROW INSERT INTO scratch VALUES (0)")
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun aTemporaryTableJoinsAndCorrelatesWithARealDiskTable() {
|
||||
val db = newDatabase()
|
||||
db.run("CREATE TABLE orders (id INTEGER PRIMARY KEY, total INTEGER)")
|
||||
db.run("INSERT INTO orders VALUES (1, 100), (2, 200)")
|
||||
db.run("CREATE TEMP TABLE flagged (order_id INTEGER)")
|
||||
db.run("INSERT INTO flagged VALUES (2)")
|
||||
|
||||
val joined = db.select(
|
||||
"SELECT orders.id, orders.total FROM orders JOIN flagged ON orders.id = flagged.order_id"
|
||||
)
|
||||
assertEquals(listOf(listOf(int(2), int(200))), joined.rows)
|
||||
|
||||
val correlated = db.select(
|
||||
"SELECT id FROM orders WHERE EXISTS (SELECT 1 FROM flagged WHERE flagged.order_id = orders.id)"
|
||||
)
|
||||
assertEquals(listOf(listOf(int(2))), correlated.rows)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun rollbackUndoesWritesToATemporaryTableEvenThoughItNeverTouchesTheWal() {
|
||||
val db = newDatabase()
|
||||
db.run("CREATE TEMP TABLE scratch (id INTEGER)")
|
||||
db.run("INSERT INTO scratch VALUES (1)")
|
||||
|
||||
db.run("BEGIN")
|
||||
db.run("INSERT INTO scratch VALUES (2), (3)")
|
||||
db.run("DELETE FROM scratch WHERE id = 1")
|
||||
assertEquals(2, db.rowCount("SELECT * FROM scratch"))
|
||||
assertEquals(RollbackResult, db.run("ROLLBACK").single())
|
||||
|
||||
assertEquals(1, db.rowCount("SELECT * FROM scratch"))
|
||||
assertEquals(listOf(int(1)), db.select("SELECT * FROM scratch").rows.single())
|
||||
}
|
||||
|
||||
@Test
|
||||
fun commitKeepsWritesToATemporaryTable() {
|
||||
val db = newDatabase()
|
||||
db.run("CREATE TEMP TABLE scratch (id INTEGER)")
|
||||
db.run("BEGIN")
|
||||
db.run("INSERT INTO scratch VALUES (1)")
|
||||
assertEquals(CommitResult, db.run("COMMIT").single())
|
||||
assertEquals(1, db.rowCount("SELECT * FROM scratch"))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun rollbackToSavepointUndoesOnlyTemporaryTableWritesAfterIt() {
|
||||
val db = newDatabase()
|
||||
db.run("CREATE TEMP TABLE scratch (id INTEGER)")
|
||||
db.run("BEGIN")
|
||||
db.run("INSERT INTO scratch VALUES (1)")
|
||||
assertEquals(SavepointResult("mark"), db.run("SAVEPOINT mark").single())
|
||||
db.run("INSERT INTO scratch VALUES (2)")
|
||||
assertEquals(2, db.rowCount("SELECT * FROM scratch"))
|
||||
|
||||
assertEquals(RollbackToSavepointResult("mark"), db.run("ROLLBACK TO SAVEPOINT mark").single())
|
||||
assertEquals(1, db.rowCount("SELECT * FROM scratch"))
|
||||
assertEquals(CommitResult, db.run("COMMIT").single())
|
||||
assertEquals(1, db.rowCount("SELECT * FROM scratch"))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun rollbackAlsoUndoesARealDiskTableWriteInTheSameTransactionAsATemporaryTableWrite() {
|
||||
val db = newDatabase()
|
||||
db.run("CREATE TABLE regular (id INTEGER PRIMARY KEY)")
|
||||
db.run("CREATE TEMP TABLE scratch (id INTEGER)")
|
||||
db.run("BEGIN")
|
||||
db.run("INSERT INTO regular VALUES (1)")
|
||||
db.run("INSERT INTO scratch VALUES (1)")
|
||||
db.run("ROLLBACK")
|
||||
assertEquals(0, db.rowCount("SELECT * FROM regular"))
|
||||
assertEquals(0, db.rowCount("SELECT * FROM scratch"))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun returningWorksOnATemporaryTable() {
|
||||
val db = newDatabase()
|
||||
db.run("CREATE TEMP TABLE scratch (id INTEGER PRIMARY KEY, note TEXT)")
|
||||
val inserted = db.run("INSERT INTO scratch VALUES (1, 'a') RETURNING id, note").single() as InsertResult
|
||||
assertEquals(SelectResult(listOf("id", "note"), listOf(listOf(int(1), text("a")))), inserted.returning)
|
||||
|
||||
val updated = db.run("UPDATE scratch SET note = 'b' WHERE id = 1 RETURNING note").single() as UpdateResult
|
||||
assertEquals(SelectResult(listOf("note"), listOf(listOf(text("b")))), updated.returning)
|
||||
|
||||
val deleted = db.run("DELETE FROM scratch WHERE id = 1 RETURNING id").single() as DeleteResult
|
||||
assertEquals(SelectResult(listOf("id"), listOf(listOf(int(1)))), deleted.returning)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun dropTableRemovesATemporaryTableWithoutAffectingCatalogTables() {
|
||||
val db = newDatabase()
|
||||
db.run("CREATE TABLE regular (id INTEGER)")
|
||||
db.run("CREATE TEMP TABLE scratch (id INTEGER)")
|
||||
db.run("DROP TABLE scratch")
|
||||
assertEquals(listOf("regular"), db.catalog.tableNames)
|
||||
assertFalse(db.catalog.tableNames.contains("scratch"))
|
||||
assertTrue(db.catalog.tableOrNull("regular") != null)
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user