test(sql): cover updateAndDeleteByFullCompositePrimaryKeyUsePointLook...

This commit is contained in:
dualfroz committed 2026-09-12 21:12:55 +02:00
1 parent aece1cdc22
commit 2501e873a3
1 file changed
+155
@@ -1432,3 +1432,158 @@ class DiskExecutorTest {
assertEquals(0, table.rangeScanCount) assertEquals(0, table.rangeScanCount)
} }
@Test
fun updateAndDeleteByFullCompositePrimaryKeyUsePointLookups() {
val db = newDatabase()
db.seedOrderLines()
val table = db.catalog.table("order_lines")
val updated = db.run("UPDATE order_lines SET sku = 'sprocket' WHERE order_id = 1 AND line_no = 1").single()
assertEquals(UpdateResult(1), updated)
assertEquals(1, table.pointLookupCount)
val deleted = db.run("DELETE FROM order_lines WHERE order_id = 2 AND line_no = 1").single()
assertEquals(DeleteResult(1), deleted)
assertEquals(2, table.pointLookupCount)
assertEquals(0, table.scanCount)
assertEquals(2, db.select("SELECT * FROM order_lines").rows.size)
}
@Test
fun aTableCannotDeclareBothAnInlinePrimaryKeyColumnAndATableLevelCompositePrimaryKey() {
val db = newDatabase()
assertFailsWith<DiskExecutorException> {
db.run("CREATE TABLE bad (id INTEGER PRIMARY KEY, other INTEGER, PRIMARY KEY (id, other))")
}
}
@Test
fun aCompositePrimaryKeyReferencingAnUnknownColumnIsRejectedWithAClearError() {
val db = newDatabase()
val failure = assertFailsWith<DiskExecutorException> {
db.run("CREATE TABLE bad (order_id INTEGER, line_no INTEGER, PRIMARY KEY (order_id, missing_column))")
}
assertTrue(failure.message!!.contains("missing_column"))
}
@Test
fun compositePrimaryKeyDataAndUniquenessSurviveClosingAndReopeningTheCatalog() {
val db = newDatabase()
db.seedOrderLines()
db.reopen()
assertFailsWith<DiskTableException> { db.run("INSERT INTO order_lines VALUES (1, 1, 'duplicate')") }
val result = db.select("SELECT sku FROM order_lines WHERE order_id = 1 AND line_no = 2")
assertEquals(listOf(listOf(text("gadget"))), result.rows)
val table = db.catalog.table("order_lines")
assertEquals(0, table.scanCount, "the point lookup above must not have fallen back to a full scan after reopening")
}
private fun Database.seedDepartments() {
run("CREATE TABLE departments (id INTEGER PRIMARY KEY, name TEXT NOT NULL, budget INTEGER)")
run("CREATE TABLE employees (id INTEGER PRIMARY KEY, name TEXT NOT NULL, department_id INTEGER, salary INTEGER)")
run("INSERT INTO departments VALUES (1, 'eng', 1000), (2, 'sales', 500), (3, 'ops', 0)")
run(
"INSERT INTO employees VALUES " +
"(1, 'ada', 1, 120), (2, 'linus', 1, 90), (3, 'grace', 2, 80), (4, 'guido', 2, 70)"
)
}
@Test
fun scalarSubqueryComparesAgainstAnUncorrelatedAggregate() {
val db = newDatabase()
db.seedDepartments()
val result = db.select("SELECT name FROM employees WHERE salary > (SELECT AVG(salary) FROM employees) ORDER BY name")
assertEquals(listOf(listOf(text("ada"))), result.rows)
}
@Test
fun scalarSubqueryReturningNoRowsEvaluatesToNull() {
val db = newDatabase()
db.seedDepartments()
val result = db.select("SELECT (SELECT id FROM departments WHERE name = 'nope') FROM departments WHERE id = 1")
assertEquals(listOf(listOf(Value.NullValue)), result.rows)
}
@Test
fun scalarSubqueryReturningMoreThanOneRowFails() {
val db = newDatabase()
db.seedDepartments()
val failure = assertFailsWith<KestrelException> {
db.select("SELECT (SELECT salary FROM employees) FROM departments WHERE id = 1")
}
assertTrue(failure.message!!.contains("more than one row"))
}
@Test
fun scalarSubqueryReturningMoreThanOneColumnFails() {
val db = newDatabase()
db.seedDepartments()
val failure = assertFailsWith<KestrelException> {
db.select("SELECT (SELECT id, name FROM departments) FROM departments WHERE id = 1")
}
assertTrue(failure.message!!.contains("exactly one column"))
}
@Test
fun correlatedScalarSubqueryInProjectionCountsPerOuterRow() {
val db = newDatabase()
db.seedDepartments()
val result = db.select(
"SELECT d.name, (SELECT COUNT(*) FROM employees e WHERE e.department_id = d.id) " +
"FROM departments d ORDER BY d.id"
)
assertEquals(
listOf(listOf(text("eng"), int(2)), listOf(text("sales"), int(2)), listOf(text("ops"), int(0))),
result.rows
)
}
@Test
fun correlatedScalarSubqueryInWhereComparesAgainstTheEmployeesOwnDepartmentAverage() {
val db = newDatabase()
db.seedDepartments()
val result = db.select(
"SELECT name FROM employees e WHERE e.salary > " +
"(SELECT AVG(salary) FROM employees e2 WHERE e2.department_id = e.department_id) ORDER BY name"
)
assertEquals(listOf(listOf(text("ada")), listOf(text("grace"))), result.rows)
}
@Test
fun inSubqueryMatchesAnUncorrelatedResultSet() {
val db = newDatabase()
db.seedDepartments()
val result = db.select("SELECT name FROM departments WHERE id IN (SELECT department_id FROM employees) ORDER BY name")
assertEquals(listOf(listOf(text("eng")), listOf(text("sales"))), result.rows)
}
@Test
fun notInSubqueryExcludesMatchingRows() {
val db = newDatabase()
db.seedDepartments()
val result = db.select("SELECT name FROM departments WHERE id NOT IN (SELECT department_id FROM employees)")
assertEquals(listOf(listOf(text("ops"))), result.rows)
}
@Test
fun notInSubqueryWithANullInTheResultSetExcludesEverythingByThreeValuedLogic() {
val db = newDatabase()
db.run("CREATE TABLE d (id INTEGER)")
db.run("CREATE TABLE e (dept INTEGER)")
db.run("INSERT INTO d VALUES (1), (2)")
db.run("INSERT INTO e VALUES (1), (NULL)")
val result = db.select("SELECT id FROM d WHERE id NOT IN (SELECT dept FROM e)")
assertEquals(emptyList(), result.rows)
}
@Test
fun inSubqueryRequiresExactlyOneColumn() {
val db = newDatabase()
db.seedDepartments()
val failure = assertFailsWith<KestrelException> {
db.select("SELECT name FROM departments WHERE id IN (SELECT id, name FROM departments)")
}
assertTrue(failure.message!!.contains("exactly one column"))
}