test: cover lagWithNoArgumentsFailsToParse

This commit is contained in:
dualfroz committed 2026-09-09 17:12:35 +02:00
1 parent 6556fa2316
commit 2377d79672
1 file changed
+173
+173
View File
@@ -1284,4 +1284,177 @@ class ParserTest {
) as SelectStatement
val windows = (statement.projection as ExpressionProjection).items.map { it.expression as WindowExpression }
assertEquals(WindowFunctionKind.FirstValue, windows[0].kind)
assertEquals(WindowFunctionKind.LastValue, windows[1].kind)
assertEquals(WindowFunctionKind.Ntile, windows[2].kind)
assertEquals(LiteralExpression(Value.IntegerValue(4)), windows[2].argument)
}
@Test
fun lagWithNoArgumentsFailsToParse() {
assertFailsWith<ParseException> { parseOne("SELECT LAG() OVER (ORDER BY id) FROM users") }
}
@Test
fun lagWithFourArgumentsFailsToParse() {
assertFailsWith<ParseException> { parseOne("SELECT LAG(salary, 1, 0, 9) OVER (ORDER BY id) FROM users") }
}
@Test
fun firstValueWithTwoArgumentsFailsToParse() {
assertFailsWith<ParseException> { parseOne("SELECT FIRST_VALUE(salary, id) OVER (ORDER BY id) FROM users") }
}
@Test
fun ntileWithNoArgumentsFailsToParse() {
assertFailsWith<ParseException> { parseOne("SELECT NTILE() OVER (ORDER BY id) FROM users") }
}
@Test
fun parsesExplicitRowsBetweenFrameWithLiteralOffsets() {
val statement = parseOne(
"SELECT SUM(salary) OVER (ORDER BY id ROWS BETWEEN 1 PRECEDING AND 2 FOLLOWING) FROM users"
) as SelectStatement
val window = (statement.projection as ExpressionProjection).items.single().expression as WindowExpression
val frame = window.frame!!
assertEquals(FrameBoundType.Preceding, frame.start.type)
assertEquals(LiteralExpression(Value.IntegerValue(1)), frame.start.offset)
assertEquals(FrameBoundType.Following, frame.end.type)
assertEquals(LiteralExpression(Value.IntegerValue(2)), frame.end.offset)
}
@Test
fun parsesUnboundedAndCurrentRowFrameBounds() {
val statement = parseOne(
"SELECT SUM(salary) OVER (ORDER BY id ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) FROM users"
) as SelectStatement
val window = (statement.projection as ExpressionProjection).items.single().expression as WindowExpression
val frame = window.frame!!
assertEquals(FrameBoundType.UnboundedPreceding, frame.start.type)
assertNull(frame.start.offset)
assertEquals(FrameBoundType.CurrentRow, frame.end.type)
assertNull(frame.end.offset)
}
@Test
fun rowsShorthandWithoutBetweenEndsAtCurrentRow() {
val statement = parseOne(
"SELECT SUM(salary) OVER (ORDER BY id ROWS 2 PRECEDING) FROM users"
) as SelectStatement
val window = (statement.projection as ExpressionProjection).items.single().expression as WindowExpression
val frame = window.frame!!
assertEquals(FrameBoundType.Preceding, frame.start.type)
assertEquals(LiteralExpression(Value.IntegerValue(2)), frame.start.offset)
assertEquals(FrameBoundType.CurrentRow, frame.end.type)
}
@Test
fun rowsShorthandWithUnboundedFollowingFailsBecauseItWouldStartAfterCurrentRow() {
assertFailsWith<ParseException> {
parseOne("SELECT SUM(salary) OVER (ORDER BY id ROWS UNBOUNDED FOLLOWING) FROM users")
}
}
@Test
fun frameStartAfterFrameEndFailsToParse() {
assertFailsWith<ParseException> {
parseOne("SELECT SUM(salary) OVER (ORDER BY id ROWS BETWEEN CURRENT ROW AND 1 PRECEDING) FROM users")
}
}
@Test
fun frameWithoutBetweenOrBoundFailsToParse() {
assertFailsWith<ParseException> {
parseOne("SELECT SUM(salary) OVER (ORDER BY id ROWS) FROM users")
}
}
@Test
fun windowWithNoFrameLeavesFrameNull() {
val statement = parseOne("SELECT SUM(salary) OVER (ORDER BY id) FROM users") as SelectStatement
val window = (statement.projection as ExpressionProjection).items.single().expression as WindowExpression
assertNull(window.frame)
}
@Test
fun parsesExplicitRangeBetweenFrameWithLiteralOffsets() {
val statement = parseOne(
"SELECT SUM(salary) OVER (ORDER BY amount RANGE BETWEEN 5 PRECEDING AND 10 FOLLOWING) FROM users"
) as SelectStatement
val window = (statement.projection as ExpressionProjection).items.single().expression as WindowExpression
val frame = window.frame!!
assertEquals(FrameUnit.Range, frame.unit)
assertEquals(FrameBoundType.Preceding, frame.start.type)
assertEquals(LiteralExpression(Value.IntegerValue(5)), frame.start.offset)
assertEquals(FrameBoundType.Following, frame.end.type)
assertEquals(LiteralExpression(Value.IntegerValue(10)), frame.end.offset)
}
@Test
fun rangeShorthandWithoutBetweenEndsAtCurrentRowAndDefaultsRowsUnitOtherwise() {
val rangeStatement = parseOne(
"SELECT SUM(salary) OVER (ORDER BY amount RANGE 3 PRECEDING) FROM users"
) as SelectStatement
val rangeWindow = (rangeStatement.projection as ExpressionProjection).items.single().expression as WindowExpression
assertEquals(FrameUnit.Range, rangeWindow.frame!!.unit)
assertEquals(FrameBoundType.CurrentRow, rangeWindow.frame!!.end.type)
val rowsStatement = parseOne(
"SELECT SUM(salary) OVER (ORDER BY amount ROWS 3 PRECEDING) FROM users"
) as SelectStatement
val rowsWindow = (rowsStatement.projection as ExpressionProjection).items.single().expression as WindowExpression
assertEquals(FrameUnit.Rows, rowsWindow.frame!!.unit)
}
@Test
fun parsesExplicitGroupsBetweenFrameWithLiteralOffsets() {
val statement = parseOne(
"SELECT SUM(salary) OVER (ORDER BY amount GROUPS BETWEEN 1 PRECEDING AND 2 FOLLOWING) FROM users"
) as SelectStatement
val window = (statement.projection as ExpressionProjection).items.single().expression as WindowExpression
val frame = window.frame!!
assertEquals(FrameUnit.Groups, frame.unit)
assertEquals(FrameBoundType.Preceding, frame.start.type)
assertEquals(LiteralExpression(Value.IntegerValue(1)), frame.start.offset)
assertEquals(FrameBoundType.Following, frame.end.type)
assertEquals(LiteralExpression(Value.IntegerValue(2)), frame.end.offset)
}
@Test
fun groupsShorthandWithoutBetweenEndsAtCurrentRow() {
val statement = parseOne(
"SELECT SUM(salary) OVER (ORDER BY amount GROUPS 3 PRECEDING) FROM users"
) as SelectStatement
val window = (statement.projection as ExpressionProjection).items.single().expression as WindowExpression
assertEquals(FrameUnit.Groups, window.frame!!.unit)
assertEquals(FrameBoundType.CurrentRow, window.frame!!.end.type)
}
@Test
fun groupsFrameStartAfterFrameEndFailsToParse() {
assertFailsWith<ParseException> {
parseOne("SELECT SUM(salary) OVER (ORDER BY amount GROUPS BETWEEN CURRENT ROW AND 1 PRECEDING) FROM users")
}
}
@Test
fun parsesRangeBetweenUnboundedAndCurrentRow() {
val statement = parseOne(
"SELECT SUM(salary) OVER (ORDER BY amount RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) FROM users"
) as SelectStatement
val window = (statement.projection as ExpressionProjection).items.single().expression as WindowExpression
val frame = window.frame!!
assertEquals(FrameUnit.Range, frame.unit)
assertEquals(FrameBoundType.UnboundedPreceding, frame.start.type)
assertEquals(FrameBoundType.CurrentRow, frame.end.type)
}
@Test
fun rangeFrameStartAfterFrameEndFailsToParse() {
assertFailsWith<ParseException> {
parseOne("SELECT SUM(salary) OVER (ORDER BY amount RANGE BETWEEN CURRENT ROW AND 1 PRECEDING) FROM users")
}
}
@Test
fun frameWithNoExcludeClauseDefaultsToNoOthers() {
}