test: cover columnLevelCollateWithAnUnknownSequenceNameFailsToParse
This commit is contained in:
1 parent
40197f5dc9
commit
6556fa2316
1 file changed
+173
@@ -1111,4 +1111,177 @@ class ParserTest {
|
||||
fun columnLevelCollateBeforeDefaultAttachesToTheColumnNotTheDefaultExpression() {
|
||||
val statement = parseOne("CREATE TABLE t (name TEXT COLLATE NOCASE DEFAULT 'x')") as CreateTableStatement
|
||||
assertEquals(Collation.NoCase, statement.columns[0].collation)
|
||||
assertEquals(LiteralExpression(Value.TextValue("x")), statement.columns[0].default)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun columnLevelCollateWithAnUnknownSequenceNameFailsToParse() {
|
||||
assertFailsWith<ParseException> { parse("CREATE TABLE t (name TEXT COLLATE BOGUS)") }
|
||||
}
|
||||
|
||||
@Test
|
||||
fun columnLevelCollateWithoutAFollowingNameFailsToParse() {
|
||||
assertFailsWith<ParseException> { parse("CREATE TABLE t (name TEXT COLLATE)") }
|
||||
}
|
||||
|
||||
@Test
|
||||
fun parsesColumnLevelCollateInAlterTableAddColumn() {
|
||||
val statement = parseOne("ALTER TABLE t ADD COLUMN name TEXT COLLATE NOCASE") as AlterTableStatement
|
||||
val action = statement.action as AddColumn
|
||||
assertEquals(Collation.NoCase, action.column.collation)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun parsesDerivedTableInFromWithRequiredAlias() {
|
||||
val statement = parseOne("SELECT s.id FROM (SELECT id FROM users) AS s") as SelectStatement
|
||||
val from = statement.from as SubquerySource
|
||||
assertEquals("s", from.alias)
|
||||
assertEquals("users", tableName(from.select))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun parsesDerivedTableWithImplicitAlias() {
|
||||
val statement = parseOne("SELECT s.id FROM (SELECT id FROM users) s") as SelectStatement
|
||||
assertEquals("s", (statement.from as SubquerySource).alias)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun derivedTableWithoutAliasFails() {
|
||||
assertFailsWith<ParseException> { parseOne("SELECT id FROM (SELECT id FROM users)") }
|
||||
}
|
||||
|
||||
@Test
|
||||
fun parsesDerivedTableAsJoinTarget() {
|
||||
val statement = parseOne(
|
||||
"SELECT * FROM users JOIN (SELECT dept, COUNT(*) AS n FROM users GROUP BY dept) AS d ON users.dept = d.dept"
|
||||
) as SelectStatement
|
||||
val joinFrom = statement.joins.single().from as SubquerySource
|
||||
assertEquals("d", joinFrom.alias)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun parsesLateralJoinMarksTheSubquerySource() {
|
||||
val statement = parseOne(
|
||||
"SELECT * FROM users u JOIN LATERAL (SELECT id FROM orders WHERE orders.userId = u.id) AS o ON TRUE"
|
||||
) as SelectStatement
|
||||
val joinFrom = statement.joins.single().from as SubquerySource
|
||||
assertEquals("o", joinFrom.alias)
|
||||
assertTrue(joinFrom.lateral)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun nonLateralDerivedTableJoinIsNotMarkedLateral() {
|
||||
val statement = parseOne("SELECT * FROM users JOIN (SELECT id FROM orders) AS o ON TRUE") as SelectStatement
|
||||
assertFalse((statement.joins.single().from as SubquerySource).lateral)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun lateralBeforeAPlainTableFails() {
|
||||
assertFailsWith<ParseException> { parseOne("SELECT * FROM users JOIN LATERAL orders ON TRUE") }
|
||||
}
|
||||
|
||||
@Test
|
||||
fun parsesRankingWindowFunctionWithPartitionAndOrder() {
|
||||
val statement = parseOne(
|
||||
"SELECT ROW_NUMBER() OVER (PARTITION BY dept ORDER BY salary DESC) AS rn FROM users"
|
||||
) as SelectStatement
|
||||
val item = (statement.projection as ExpressionProjection).items.single()
|
||||
val window = item.expression as WindowExpression
|
||||
assertEquals("ROW_NUMBER", window.name)
|
||||
assertEquals(WindowFunctionKind.RowNumber, window.kind)
|
||||
assertNull(window.argument)
|
||||
assertFalse(window.star)
|
||||
assertEquals(listOf(ColumnExpression("dept")), window.partitionBy)
|
||||
assertEquals(1, window.orderBy.size)
|
||||
assertEquals(ColumnExpression("salary"), window.orderBy.single().expression)
|
||||
assertTrue(window.orderBy.single().descending)
|
||||
assertEquals("rn", item.alias)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun parsesAggregateWindowFunctionWithStarAndNoPartition() {
|
||||
val statement = parseOne("SELECT COUNT(*) OVER () FROM users") as SelectStatement
|
||||
val window = (statement.projection as ExpressionProjection).items.single().expression as WindowExpression
|
||||
assertEquals(WindowFunctionKind.Aggregate, window.kind)
|
||||
assertTrue(window.star)
|
||||
assertNull(window.argument)
|
||||
assertTrue(window.partitionBy.isEmpty())
|
||||
assertTrue(window.orderBy.isEmpty())
|
||||
}
|
||||
|
||||
@Test
|
||||
fun aggregateWindowFunctionWithSingleArgumentAndOrderBy() {
|
||||
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
|
||||
assertEquals("SUM", window.name)
|
||||
assertEquals(ColumnExpression("salary"), window.argument)
|
||||
assertFalse(window.star)
|
||||
assertEquals(listOf(ColumnExpression("id")), window.orderBy.map { it.expression })
|
||||
}
|
||||
|
||||
@Test
|
||||
fun windowOverOrderByParsesAnExplicitNullsFirstClause() {
|
||||
val statement = parseOne("SELECT SUM(salary) OVER (ORDER BY bonus NULLS FIRST) FROM users") as SelectStatement
|
||||
val window = (statement.projection as ExpressionProjection).items.single().expression as WindowExpression
|
||||
val key = window.orderBy.single()
|
||||
assertEquals(ColumnExpression("bonus"), key.expression)
|
||||
assertEquals(false, key.descending)
|
||||
assertEquals(true, key.nullsFirst)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun functionNameWithoutOverIsNotTreatedAsAWindowFunction() {
|
||||
val statement = parseOne("SELECT ROW_NUMBER() FROM users") as SelectStatement
|
||||
val expression = (statement.projection as ExpressionProjection).items.single().expression
|
||||
assertTrue(expression is CallExpression)
|
||||
assertEquals("ROW_NUMBER", (expression as CallExpression).name)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun rowNumberWithArgumentsFailsToParse() {
|
||||
assertFailsWith<ParseException> { parseOne("SELECT ROW_NUMBER(id) OVER () FROM users") }
|
||||
}
|
||||
|
||||
@Test
|
||||
fun rankWithAnArgumentFailsToParse() {
|
||||
assertFailsWith<ParseException> { parseOne("SELECT RANK(id) OVER (ORDER BY id) FROM users") }
|
||||
}
|
||||
|
||||
@Test
|
||||
fun nonWindowableFunctionBeforeOverFailsToParse() {
|
||||
assertFailsWith<ParseException> { parseOne("SELECT UPPER(name) OVER () FROM users") }
|
||||
}
|
||||
|
||||
@Test
|
||||
fun lagWithOffsetAndDefaultParsesIntoTheirOwnFields() {
|
||||
val statement = parseOne(
|
||||
"SELECT LAG(salary, 2, 0) OVER (PARTITION BY dept ORDER BY id) AS prev FROM users"
|
||||
) as SelectStatement
|
||||
val window = (statement.projection as ExpressionProjection).items.single().expression as WindowExpression
|
||||
assertEquals("LAG", window.name)
|
||||
assertEquals(WindowFunctionKind.Lag, window.kind)
|
||||
assertEquals(ColumnExpression("salary"), window.argument)
|
||||
assertEquals(LiteralExpression(Value.IntegerValue(2)), window.offset)
|
||||
assertEquals(LiteralExpression(Value.IntegerValue(0)), window.defaultValue)
|
||||
assertFalse(window.star)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun leadWithASingleArgumentLeavesOffsetAndDefaultNull() {
|
||||
val statement = parseOne("SELECT LEAD(salary) OVER (ORDER BY id) FROM users") as SelectStatement
|
||||
val window = (statement.projection as ExpressionProjection).items.single().expression as WindowExpression
|
||||
assertEquals(WindowFunctionKind.Lead, window.kind)
|
||||
assertEquals(ColumnExpression("salary"), window.argument)
|
||||
assertNull(window.offset)
|
||||
assertNull(window.defaultValue)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun parsesFirstValueLastValueAndNtile() {
|
||||
val statement = parseOne(
|
||||
"SELECT FIRST_VALUE(salary) OVER (ORDER BY id), LAST_VALUE(salary) OVER (ORDER BY id), " +
|
||||
"NTILE(4) OVER (ORDER BY id) FROM users"
|
||||
) as SelectStatement
|
||||
val windows = (statement.projection as ExpressionProjection).items.map { it.expression as WindowExpression }
|
||||
assertEquals(WindowFunctionKind.FirstValue, windows[0].kind)
|
||||
}
|
||||
Reference in new issue
Block a user