test: cover defaultAppliesIndependentlyToEachOmittedColumn
This commit is contained in:
1 parent
f8d57f5621
commit
4216c1c5eb
1 file changed
+163
@@ -470,3 +470,166 @@ class AlterTableTest {
|
|||||||
assertEquals(listOf(listOf(Value.NullValue)), select("SELECT status FROM t").rows)
|
assertEquals(listOf(listOf(Value.NullValue)), select("SELECT status FROM t").rows)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun defaultAppliesIndependentlyToEachOmittedColumn() {
|
||||||
|
run("CREATE TABLE t (id INTEGER PRIMARY KEY, status TEXT DEFAULT 'new', score INTEGER DEFAULT 0)")
|
||||||
|
run("INSERT INTO t (id) VALUES (1)")
|
||||||
|
val result = exec("INSERT INTO t (id) VALUES (2)")
|
||||||
|
assertEquals(InsertResult(1), result)
|
||||||
|
assertEquals(
|
||||||
|
listOf(listOf(text("new"), int(0)), listOf(text("new"), int(0))),
|
||||||
|
select("SELECT status, score FROM t ORDER BY id ASC").rows
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun createTableRejectsColumnReferenceInDefault() {
|
||||||
|
val error = assertFailsWith<KestrelException> {
|
||||||
|
run("CREATE TABLE t (id INTEGER PRIMARY KEY, twice INTEGER DEFAULT id)")
|
||||||
|
}
|
||||||
|
assertTrue(error.message!!.contains("DEFAULT"))
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun createTableRejectsSubqueryInDefault() {
|
||||||
|
run("CREATE TABLE other (x INTEGER)")
|
||||||
|
assertFailsWith<KestrelException> {
|
||||||
|
run("CREATE TABLE t (id INTEGER PRIMARY KEY, x INTEGER DEFAULT (SELECT COUNT(*) FROM other))")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun createTableRejectsAggregateInDefault() {
|
||||||
|
val error = assertFailsWith<KestrelException> {
|
||||||
|
run("CREATE TABLE t (id INTEGER PRIMARY KEY, x INTEGER DEFAULT COUNT(*))")
|
||||||
|
}
|
||||||
|
assertTrue(error.message!!.contains("aggregate"))
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun createTableValidatesDefaultTypeEagerly() {
|
||||||
|
assertFailsWith<KestrelException> {
|
||||||
|
run("CREATE TABLE t (id INTEGER PRIMARY KEY, age INTEGER DEFAULT 'not a number')")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ---- DEFAULT (UPDATE) ----
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun updateSetToDefaultResetsTheColumnToItsDeclaredDefault() {
|
||||||
|
run("CREATE TABLE t (id INTEGER PRIMARY KEY, status TEXT DEFAULT 'pending')")
|
||||||
|
run("INSERT INTO t VALUES (1, 'shipped')")
|
||||||
|
val result = exec("UPDATE t SET status = DEFAULT WHERE id = 1")
|
||||||
|
assertEquals(UpdateResult(1), result)
|
||||||
|
assertEquals(listOf(listOf(text("pending"))), select("SELECT status FROM t").rows)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun updateSetToDefaultFallsBackToNullWhenTheColumnHasNoDeclaredDefault() {
|
||||||
|
run("CREATE TABLE t (id INTEGER PRIMARY KEY, note TEXT)")
|
||||||
|
run("INSERT INTO t VALUES (1, 'keep me')")
|
||||||
|
run("UPDATE t SET note = DEFAULT WHERE id = 1")
|
||||||
|
assertEquals(listOf(listOf(Value.NullValue)), select("SELECT note FROM t").rows)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun updateSetToDefaultIsEvaluatedFreshPerRowJustLikeInsert() {
|
||||||
|
run("CREATE TABLE t (id INTEGER PRIMARY KEY, score INTEGER DEFAULT 0)")
|
||||||
|
run("INSERT INTO t VALUES (1, 10), (2, 20), (3, 30)")
|
||||||
|
val result = exec("UPDATE t SET score = DEFAULT WHERE id IN (1, 2)")
|
||||||
|
assertEquals(UpdateResult(2), result)
|
||||||
|
assertEquals(
|
||||||
|
listOf(listOf(int(1), int(0)), listOf(int(2), int(0)), listOf(int(3), int(30))),
|
||||||
|
select("SELECT id, score FROM t ORDER BY id ASC").rows
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun updateCanMixADefaultAssignmentWithARegularAssignmentInTheSameStatement() {
|
||||||
|
run("CREATE TABLE t (id INTEGER PRIMARY KEY, name TEXT, status TEXT DEFAULT 'pending')")
|
||||||
|
run("INSERT INTO t VALUES (1, 'ada', 'shipped')")
|
||||||
|
run("UPDATE t SET name = 'grace', status = DEFAULT WHERE id = 1")
|
||||||
|
assertEquals(listOf(listOf(text("grace"), text("pending"))), select("SELECT name, status FROM t").rows)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun updateSetToDefaultFailsNotNullValidationWhenThereIsNoDefaultToFallBackOn() {
|
||||||
|
run("CREATE TABLE t (id INTEGER PRIMARY KEY, status TEXT NOT NULL)")
|
||||||
|
run("INSERT INTO t VALUES (1, 'shipped')")
|
||||||
|
val error = assertFailsWith<KestrelException> {
|
||||||
|
run("UPDATE t SET status = DEFAULT WHERE id = 1")
|
||||||
|
}
|
||||||
|
assertTrue(error.message!!.contains("status"), error.message!!)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun updateSetToDefaultRoundTripsThroughSqlWriter() {
|
||||||
|
run("CREATE TABLE t (id INTEGER PRIMARY KEY, status TEXT DEFAULT 'pending')")
|
||||||
|
run("INSERT INTO t VALUES (1, 'shipped')")
|
||||||
|
val statement = Parser(Lexer("UPDATE t SET status = DEFAULT WHERE id = 1").tokenize()).parseProgram().single()
|
||||||
|
val rendered = SqlWriter.write(statement)
|
||||||
|
assertTrue(rendered.contains("status = DEFAULT"), rendered)
|
||||||
|
run(rendered)
|
||||||
|
assertEquals(listOf(listOf(text("pending"))), select("SELECT status FROM t").rows)
|
||||||
|
}
|
||||||
|
|
||||||
|
// ---- DEFAULT (INSERT VALUES) ----
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun insertValuesWithLiteralDefaultUsesTheColumnsDeclaredDefault() {
|
||||||
|
run("CREATE TABLE t (id INTEGER PRIMARY KEY, status TEXT DEFAULT 'pending')")
|
||||||
|
val result = exec("INSERT INTO t VALUES (1, DEFAULT)")
|
||||||
|
assertEquals(InsertResult(1), result)
|
||||||
|
assertEquals(listOf(listOf(text("pending"))), select("SELECT status FROM t").rows)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun insertValuesWithLiteralDefaultFallsBackToNullWhenTheColumnHasNoDeclaredDefault() {
|
||||||
|
run("CREATE TABLE t (id INTEGER PRIMARY KEY, note TEXT)")
|
||||||
|
run("INSERT INTO t VALUES (1, DEFAULT)")
|
||||||
|
assertEquals(listOf(listOf(Value.NullValue)), select("SELECT note FROM t").rows)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun insertValuesLiteralDefaultIsDistinctFromAnExplicitNullLiteral() {
|
||||||
|
run("CREATE TABLE t (id INTEGER PRIMARY KEY, status TEXT DEFAULT 'pending')")
|
||||||
|
run("INSERT INTO t VALUES (1, NULL)")
|
||||||
|
assertEquals(listOf(listOf(Value.NullValue)), select("SELECT status FROM t").rows)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun insertValuesLiteralDefaultAppliesIndependentlyToEachRowInAMultiRowInsert() {
|
||||||
|
run("CREATE TABLE t (id INTEGER PRIMARY KEY, score INTEGER DEFAULT 0)")
|
||||||
|
run("INSERT INTO t VALUES (1, DEFAULT), (2, 20), (3, DEFAULT)")
|
||||||
|
assertEquals(
|
||||||
|
listOf(listOf(int(1), int(0)), listOf(int(2), int(20)), listOf(int(3), int(0))),
|
||||||
|
select("SELECT id, score FROM t ORDER BY id ASC").rows
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun insertValuesLiteralDefaultWorksWithAnExplicitColumnList() {
|
||||||
|
run("CREATE TABLE t (id INTEGER PRIMARY KEY, name TEXT, status TEXT DEFAULT 'pending')")
|
||||||
|
run("INSERT INTO t (id, status, name) VALUES (1, DEFAULT, 'ada')")
|
||||||
|
assertEquals(listOf(listOf(text("ada"), text("pending"))), select("SELECT name, status FROM t").rows)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun insertValuesLiteralDefaultFailsNotNullValidationWhenThereIsNoDefaultToFallBackOn() {
|
||||||
|
run("CREATE TABLE t (id INTEGER PRIMARY KEY, status TEXT NOT NULL)")
|
||||||
|
val error = assertFailsWith<KestrelException> {
|
||||||
|
run("INSERT INTO t VALUES (1, DEFAULT)")
|
||||||
|
}
|
||||||
|
assertTrue(error.message!!.contains("status"), error.message!!)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun insertValuesLiteralDefaultRoundTripsThroughSqlWriter() {
|
||||||
|
run("CREATE TABLE t (id INTEGER PRIMARY KEY, status TEXT DEFAULT 'pending')")
|
||||||
|
val statement = Parser(Lexer("INSERT INTO t VALUES (1, DEFAULT)").tokenize()).parseProgram().single()
|
||||||
|
val rendered = SqlWriter.write(statement)
|
||||||
|
assertTrue(rendered.contains("DEFAULT"), rendered)
|
||||||
|
run(rendered)
|
||||||
|
assertEquals(listOf(listOf(text("pending"))), select("SELECT status FROM t").rows)
|
||||||
|
}
|
||||||
|
|
||||||
Reference in new issue
Block a user