test: cover alterTableAddColumnGeneratedRejectsCombiningWithDefault

This commit is contained in:
dualfroz committed 2026-09-09 17:36:18 +02:00
1 parent 22f6ce2ed4
commit 33a0168223
1 file changed
+173
+173
View File
@@ -1803,4 +1803,177 @@ class ParserTest {
@Test
fun parsesGeneratedAlwaysAsStoredInAlterTableAddColumn() {
val statement = parseOne("ALTER TABLE t ADD COLUMN b INTEGER GENERATED ALWAYS AS (a * 2) STORED") as AlterTableStatement
val column = (statement.action as AddColumn).column
assertEquals(
BinaryExpression(BinaryOperator.Multiply, ColumnExpression("a"), LiteralExpression(Value.IntegerValue(2))),
column.generated
)
assertEquals(null, column.default)
}
@Test
fun alterTableAddColumnGeneratedRejectsCombiningWithDefault() {
assertFailsWith<ParseException> {
parse("ALTER TABLE t ADD COLUMN b INTEGER DEFAULT 1 GENERATED ALWAYS AS (a) STORED")
}
}
@Test
fun alterTableAddColumnGeneratedStillRejectsPrimaryKey() {
assertFailsWith<ParseException> {
parse("ALTER TABLE t ADD COLUMN b INTEGER GENERATED ALWAYS AS (a) STORED PRIMARY KEY")
}
}
@Test
fun parsesCreateTriggerWithTimingEventAndBody() {
val statement = parseOne(
"CREATE TRIGGER log AFTER INSERT ON orders FOR EACH ROW BEGIN INSERT INTO audit VALUES (NEW.id); END"
) as CreateTriggerStatement
assertEquals("log", statement.triggerName)
assertEquals(TriggerTiming.After, statement.timing)
assertEquals(TriggerEvent.Insert, statement.event)
assertEquals("orders", statement.tableName)
assertEquals(null, statement.whenClause)
assertEquals(1, statement.body.size)
assertTrue(statement.body.single() is InsertStatement)
}
@Test
fun parsesCreateTriggerWithWhenClauseAndMultipleBodyStatements() {
val statement = parseOne(
"CREATE TRIGGER guard BEFORE UPDATE ON accounts FOR EACH ROW WHEN NEW.balance < 0 " +
"BEGIN UPDATE accounts SET balance = 0 WHERE id = NEW.id; DELETE FROM overdrafts WHERE account_id = NEW.id; END"
) as CreateTriggerStatement
assertEquals(TriggerTiming.Before, statement.timing)
assertEquals(TriggerEvent.Update, statement.event)
assertTrue(statement.whenClause is BinaryExpression)
assertEquals(2, statement.body.size)
assertTrue(statement.body[0] is UpdateStatement)
assertTrue(statement.body[1] is DeleteStatement)
}
@Test
fun parsesDropTrigger() {
val statement = parseOne("DROP TRIGGER log") as DropTriggerStatement
assertEquals("log", statement.triggerName)
}
@Test
fun createTriggerRejectsNonDmlBodyStatement() {
assertFailsWith<ParseException> { parse("CREATE TRIGGER log AFTER INSERT ON t FOR EACH ROW BEGIN SELECT 1; END") }
}
@Test
fun createTriggerRequiresForEachRow() {
assertFailsWith<ParseException> { parse("CREATE TRIGGER log AFTER INSERT ON t BEGIN DELETE FROM t WHERE 1 = 0; END") }
}
@Test
fun createTriggerRequiresMatchingEnd() {
assertFailsWith<ParseException> { parse("CREATE TRIGGER log AFTER INSERT ON t FOR EACH ROW BEGIN DELETE FROM t WHERE 1 = 0;") }
}
@Test
fun createTriggerRequiresTimingAndEventKeywords() {
assertFailsWith<ParseException> { parse("CREATE TRIGGER log ON t FOR EACH ROW BEGIN DELETE FROM t WHERE 1 = 0; END") }
assertFailsWith<ParseException> { parse("CREATE TRIGGER log AFTER ON t FOR EACH ROW BEGIN DELETE FROM t WHERE 1 = 0; END") }
}
@Test
fun parsesCreateSequenceWithNoOptions() {
val statement = parseOne("CREATE SEQUENCE seq") as CreateSequenceStatement
assertEquals("seq", statement.sequenceName)
assertEquals(null, statement.incrementBy)
assertEquals(null, statement.minValue)
assertEquals(null, statement.maxValue)
assertEquals(null, statement.startValue)
assertEquals(false, statement.cycle)
}
@Test
fun parsesCreateSequenceWithEveryOptionInAnyOrder() {
val statement = parseOne("CREATE SEQUENCE seq CYCLE START WITH 10 MAXVALUE 100 MINVALUE 1 INCREMENT BY 2") as CreateSequenceStatement
assertEquals(2L, statement.incrementBy)
assertEquals(1L, statement.minValue)
assertEquals(100L, statement.maxValue)
assertEquals(10L, statement.startValue)
assertEquals(true, statement.cycle)
}
@Test
fun parsesCreateSequenceWithNegativeBounds() {
val statement = parseOne("CREATE SEQUENCE seq INCREMENT BY -1 MINVALUE -100 START WITH -1") as CreateSequenceStatement
assertEquals(-1L, statement.incrementBy)
assertEquals(-100L, statement.minValue)
assertEquals(-1L, statement.startValue)
}
@Test
fun parsesDropSequence() {
val statement = parseOne("DROP SEQUENCE seq") as DropSequenceStatement
assertEquals("seq", statement.sequenceName)
}
@Test
fun parsesAlterSequenceRestartWithAndIncrementBy() {
val statement = parseOne("ALTER SEQUENCE seq INCREMENT BY 5 RESTART WITH 1") as AlterSequenceStatement
assertEquals("seq", statement.sequenceName)
assertEquals(5L, statement.incrementBy)
assertEquals(true, statement.restart)
assertEquals(1L, statement.restartWith)
}
@Test
fun parsesAlterSequenceBareRestart() {
val statement = parseOne("ALTER SEQUENCE seq RESTART") as AlterSequenceStatement
assertEquals(true, statement.restart)
assertEquals(null, statement.restartWith)
}
@Test
fun parsesAlterSequenceNoMinvalueNoMaxvalueNoCycle() {
val statement = parseOne("ALTER SEQUENCE seq NO MINVALUE NO MAXVALUE NO CYCLE") as AlterSequenceStatement
assertEquals(true, statement.clearMinValue)
assertEquals(true, statement.clearMaxValue)
assertEquals(false, statement.cycle)
}
@Test
fun alterDispatchesToTableOrSequenceByFollowingKeyword() {
assertTrue(parseOne("ALTER TABLE t ADD COLUMN x INTEGER") is AlterTableStatement)
assertTrue(parseOne("ALTER SEQUENCE seq INCREMENT BY 1") is AlterSequenceStatement)
assertFailsWith<ParseException> { parse("ALTER VIEW v RENAME TO v2") }
}
@Test
fun parsesNextvalAndCurrvalAsDedicatedExpressions() {
val select = parseOne("SELECT NEXTVAL('seq'), CURRVAL('seq') FROM t") as SelectStatement
val items = (select.projection as ExpressionProjection).items
assertEquals(NextValueExpression("seq"), items[0].expression)
assertEquals(CurrentValueExpression("seq"), items[1].expression)
}
@Test
fun nextvalRequiresASingleStringLiteralArgument() {
assertFailsWith<ParseException> { parse("SELECT NEXTVAL(seq_column)") }
assertFailsWith<ParseException> { parse("SELECT NEXTVAL('a', 'b')") }
assertFailsWith<ParseException> { parse("SELECT NEXTVAL()") }
}
@Test
fun parsesGroupByRollup() {
val statement = parseOne("SELECT dept, region, SUM(amount) FROM sales GROUP BY ROLLUP (dept, region)") as SelectStatement
val spec = statement.groupingSpec as RollupSpec
assertEquals(listOf("dept", "region"), spec.expressions.map { (it as ColumnExpression).name })
assertEquals(listOf("dept", "region"), statement.groupBy.map { (it as ColumnExpression).name })
}
@Test
fun parsesGroupByCube() {
val statement = parseOne("SELECT dept, region, SUM(amount) FROM sales GROUP BY CUBE (dept, region)") as SelectStatement
val spec = statement.groupingSpec as CubeSpec
assertEquals(listOf("dept", "region"), spec.expressions.map { (it as ColumnExpression).name })
}
}