test(sql): cover existsWithoutCorrelationChecksOnlyWhetherTheSubquery...
This commit is contained in:
1 parent
2501e873a3
commit
63cb6f5d6a
1 file changed
+157
@@ -1587,3 +1587,160 @@ class DiskExecutorTest {
|
||||
assertTrue(failure.message!!.contains("exactly one column"))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun existsWithoutCorrelationChecksOnlyWhetherTheSubqueryHasAnyRows() {
|
||||
val db = newDatabase()
|
||||
db.seedDepartments()
|
||||
val result = db.select("SELECT name FROM departments WHERE EXISTS (SELECT 1 FROM employees) ORDER BY name")
|
||||
assertEquals(listOf(listOf(text("eng")), listOf(text("ops")), listOf(text("sales"))), result.rows)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun correlatedExistsFindsDepartmentsWithEmployees() {
|
||||
val db = newDatabase()
|
||||
db.seedDepartments()
|
||||
val result = db.select(
|
||||
"SELECT name FROM departments d WHERE EXISTS " +
|
||||
"(SELECT 1 FROM employees e WHERE e.department_id = d.id) ORDER BY name"
|
||||
)
|
||||
assertEquals(listOf(listOf(text("eng")), listOf(text("sales"))), result.rows)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun correlatedNotExistsFindsDepartmentsWithoutEmployees() {
|
||||
val db = newDatabase()
|
||||
db.seedDepartments()
|
||||
val result = db.select(
|
||||
"SELECT name FROM departments d WHERE NOT EXISTS (SELECT 1 FROM employees e WHERE e.department_id = d.id)"
|
||||
)
|
||||
assertEquals(listOf(listOf(text("ops"))), result.rows)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun nestedSubqueriesCorrelateAcrossTwoLevelsOfOuterRows() {
|
||||
val db = newDatabase()
|
||||
db.seedDepartments()
|
||||
val result = db.select(
|
||||
"SELECT d.name FROM departments d WHERE EXISTS (" +
|
||||
"SELECT 1 FROM employees e WHERE e.department_id = d.id AND e.salary > (" +
|
||||
"SELECT AVG(salary) FROM employees e2 WHERE e2.department_id = d.id" +
|
||||
")) ORDER BY d.name"
|
||||
)
|
||||
assertEquals(listOf(listOf(text("eng")), listOf(text("sales"))), result.rows)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun correlatedScalarSubqueryIsUsableInUpdateSet() {
|
||||
val db = newDatabase()
|
||||
db.seedDepartments()
|
||||
db.run("CREATE TABLE dept_stats (id INTEGER PRIMARY KEY, headcount INTEGER)")
|
||||
db.run("INSERT INTO dept_stats VALUES (1, 0), (2, 0), (3, 0)")
|
||||
db.run(
|
||||
"UPDATE dept_stats SET headcount = " +
|
||||
"(SELECT COUNT(*) FROM employees WHERE employees.department_id = dept_stats.id)"
|
||||
)
|
||||
val result = db.select("SELECT headcount FROM dept_stats ORDER BY id")
|
||||
assertEquals(listOf(listOf(int(2)), listOf(int(2)), listOf(int(0))), result.rows)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun inSubqueryIsUsableInDeleteWhereClause() {
|
||||
val db = newDatabase()
|
||||
db.seedDepartments()
|
||||
db.run("INSERT INTO employees VALUES (5, 'temp', 3, 10)")
|
||||
db.run("DELETE FROM employees WHERE department_id IN (SELECT id FROM departments WHERE budget = 0)")
|
||||
val result = db.select("SELECT name FROM employees ORDER BY name")
|
||||
assertEquals(
|
||||
listOf(listOf(text("ada")), listOf(text("grace")), listOf(text("guido")), listOf(text("linus"))),
|
||||
result.rows
|
||||
)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun scalarSubqueryIsUsableAsAnInsertValue() {
|
||||
val db = newDatabase()
|
||||
db.seedDepartments()
|
||||
db.run("CREATE TABLE summary (id INTEGER PRIMARY KEY, employee_count INTEGER)")
|
||||
db.run("INSERT INTO summary VALUES (1, (SELECT COUNT(*) FROM employees))")
|
||||
val result = db.select("SELECT employee_count FROM summary")
|
||||
assertEquals(listOf(listOf(int(4))), result.rows)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun aggregateOverAnUncorrelatedScalarSubqueryEvaluatesItPerRow() {
|
||||
val db = newDatabase()
|
||||
db.seedDepartments()
|
||||
val result = db.select("SELECT SUM((SELECT budget FROM departments WHERE id = 1)) FROM employees")
|
||||
assertEquals(listOf(listOf(int(1000 * 4))), result.rows)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun existsResultCannotBeUsedAsAnArithmeticOperand() {
|
||||
val db = newDatabase()
|
||||
db.seedDepartments()
|
||||
assertFailsWith<KestrelException> {
|
||||
db.select("SELECT 1 + EXISTS (SELECT 1 FROM employees) FROM departments WHERE id = 1")
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun aSubqueryReferencingAnUnknownColumnFailsWithAClearError() {
|
||||
val db = newDatabase()
|
||||
db.seedDepartments()
|
||||
val failure = assertFailsWith<KestrelException> {
|
||||
db.select("SELECT (SELECT missing_column FROM employees) FROM departments")
|
||||
}
|
||||
assertTrue(failure.message!!.contains("missing_column"))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun subqueryAgainstADerivedTableInsideItselfWorks() {
|
||||
val db = newDatabase()
|
||||
db.seedDepartments()
|
||||
val matches = db.select(
|
||||
"SELECT name FROM departments WHERE EXISTS " +
|
||||
"(SELECT 1 FROM (SELECT id FROM employees WHERE salary > 100) sub) ORDER BY name"
|
||||
)
|
||||
assertEquals(listOf(text("eng"), text("ops"), text("sales")), matches.rows.map { it.single() })
|
||||
|
||||
val none = db.select(
|
||||
"SELECT name FROM departments WHERE EXISTS (SELECT 1 FROM (SELECT id FROM employees WHERE salary > 1000) sub)"
|
||||
)
|
||||
assertEquals(emptyList(), none.rows)
|
||||
}
|
||||
|
||||
private fun Database.seedCompound() {
|
||||
run("CREATE TABLE dual (x INTEGER)")
|
||||
run("INSERT INTO dual VALUES (1)")
|
||||
run("CREATE TABLE t1 (id INTEGER PRIMARY KEY, name TEXT NOT NULL)")
|
||||
run("CREATE TABLE t2 (id INTEGER PRIMARY KEY, name TEXT NOT NULL)")
|
||||
run("INSERT INTO t1 VALUES (1, 'ada'), (2, 'linus')")
|
||||
run("INSERT INTO t2 VALUES (2, 'linus'), (3, 'grace')")
|
||||
}
|
||||
|
||||
@Test
|
||||
fun unionRemovesDuplicateRows() {
|
||||
val db = newDatabase()
|
||||
db.seedCompound()
|
||||
val result = db.select("SELECT name FROM t1 UNION SELECT name FROM t2 ORDER BY name")
|
||||
assertEquals(listOf(listOf(text("ada")), listOf(text("grace")), listOf(text("linus"))), result.rows)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun unionAllKeepsDuplicateRows() {
|
||||
val db = newDatabase()
|
||||
db.seedCompound()
|
||||
val result = db.select("SELECT name FROM t1 UNION ALL SELECT name FROM t2 ORDER BY name")
|
||||
assertEquals(
|
||||
listOf(listOf(text("ada")), listOf(text("grace")), listOf(text("linus")), listOf(text("linus"))),
|
||||
result.rows
|
||||
)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun intersectReturnsRowsPresentInBothQueries() {
|
||||
val db = newDatabase()
|
||||
db.seedCompound()
|
||||
assertEquals(listOf(listOf(text("linus"))), db.select("SELECT name FROM t1 INTERSECT SELECT name FROM t2").rows)
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user