test: cover parsesEveryExcludeMode and excludeOf
This commit is contained in:
1 parent
2377d79672
commit
327e8f2431
1 file changed
+173
@@ -1457,4 +1457,177 @@ class ParserTest {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun frameWithNoExcludeClauseDefaultsToNoOthers() {
|
fun frameWithNoExcludeClauseDefaultsToNoOthers() {
|
||||||
|
val statement = parseOne(
|
||||||
|
"SELECT SUM(salary) OVER (ORDER BY id ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING) FROM users"
|
||||||
|
) as SelectStatement
|
||||||
|
val window = (statement.projection as ExpressionProjection).items.single().expression as WindowExpression
|
||||||
|
assertEquals(FrameExclude.NoOthers, window.frame!!.exclude)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun parsesEveryExcludeMode() {
|
||||||
|
fun excludeOf(clause: String): FrameExclude {
|
||||||
|
val statement = parseOne(
|
||||||
|
"SELECT SUM(salary) OVER (ORDER BY id ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING $clause) FROM users"
|
||||||
|
) as SelectStatement
|
||||||
|
val window = (statement.projection as ExpressionProjection).items.single().expression as WindowExpression
|
||||||
|
return window.frame!!.exclude
|
||||||
|
}
|
||||||
|
assertEquals(FrameExclude.CurrentRow, excludeOf("EXCLUDE CURRENT ROW"))
|
||||||
|
assertEquals(FrameExclude.Group, excludeOf("EXCLUDE GROUP"))
|
||||||
|
assertEquals(FrameExclude.Ties, excludeOf("EXCLUDE TIES"))
|
||||||
|
assertEquals(FrameExclude.NoOthers, excludeOf("EXCLUDE NO OTHERS"))
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun excludeWithoutAValidModeFailsToParse() {
|
||||||
|
assertFailsWith<ParseException> {
|
||||||
|
parseOne(
|
||||||
|
"SELECT SUM(salary) OVER (ORDER BY id ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING EXCLUDE FOO) FROM users"
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun parsesUnionAsASetOperationStatement() {
|
||||||
|
val statement = parseOne("SELECT id FROM a UNION SELECT id FROM b") as SetOperationStatement
|
||||||
|
assertEquals(SetOperator.Union, statement.operator)
|
||||||
|
assertEquals("a", tableName(statement.left))
|
||||||
|
assertEquals("b", tableName(statement.right))
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun parsesUnionAllIntersectAndExcept() {
|
||||||
|
assertEquals(SetOperator.UnionAll, (parseOne("SELECT id FROM a UNION ALL SELECT id FROM b") as SetOperationStatement).operator)
|
||||||
|
assertEquals(SetOperator.Intersect, (parseOne("SELECT id FROM a INTERSECT SELECT id FROM b") as SetOperationStatement).operator)
|
||||||
|
assertEquals(SetOperator.Except, (parseOne("SELECT id FROM a EXCEPT SELECT id FROM b") as SetOperationStatement).operator)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun parsesIntersectAllAndExceptAll() {
|
||||||
|
assertEquals(SetOperator.IntersectAll, (parseOne("SELECT id FROM a INTERSECT ALL SELECT id FROM b") as SetOperationStatement).operator)
|
||||||
|
assertEquals(SetOperator.ExceptAll, (parseOne("SELECT id FROM a EXCEPT ALL SELECT id FROM b") as SetOperationStatement).operator)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun parsesCreateIndexAndCreateUniqueIndex() {
|
||||||
|
val plain = parseOne("CREATE INDEX idx ON t (a)") as CreateIndexStatement
|
||||||
|
assertEquals(false, plain.unique)
|
||||||
|
assertEquals("idx", plain.indexName)
|
||||||
|
assertEquals("t", plain.tableName)
|
||||||
|
assertEquals(listOf("a"), plain.columnNames)
|
||||||
|
val unique = parseOne("CREATE UNIQUE INDEX idx ON t (a)") as CreateIndexStatement
|
||||||
|
assertEquals(true, unique.unique)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun chainedCompoundOperatorsAreLeftAssociative() {
|
||||||
|
val statement = parseOne("SELECT id FROM a UNION SELECT id FROM b INTERSECT SELECT id FROM c") as SetOperationStatement
|
||||||
|
assertEquals(SetOperator.Intersect, statement.operator)
|
||||||
|
val left = statement.left as SetOperationStatement
|
||||||
|
assertEquals(SetOperator.Union, left.operator)
|
||||||
|
assertEquals("a", tableName(left.left))
|
||||||
|
assertEquals("b", tableName(left.right))
|
||||||
|
assertEquals("c", tableName(statement.right))
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun trailingOrderByAndLimitAttachToTheWholeCompoundQuery() {
|
||||||
|
val statement = parseOne("SELECT id FROM a UNION SELECT id FROM b ORDER BY id DESC LIMIT 3") as SetOperationStatement
|
||||||
|
val key = statement.orderBy!!.keys.single()
|
||||||
|
assertEquals("id", (key.expression as ColumnExpression).name)
|
||||||
|
assertEquals(true, key.descending)
|
||||||
|
assertEquals(3, statement.limit)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun individualSelectCoresInACompoundQueryDoNotOwnOrderByOrLimit() {
|
||||||
|
val statement = parseOne("SELECT id FROM a UNION SELECT id FROM b") as SetOperationStatement
|
||||||
|
assertNull((statement.left as SelectStatement).orderBy)
|
||||||
|
assertNull((statement.left as SelectStatement).limit)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun parsesWithClauseAsAWithQuery() {
|
||||||
|
val statement = parseOne("WITH recent AS (SELECT id FROM a) SELECT id FROM recent") as WithQuery
|
||||||
|
assertEquals(false, statement.recursive)
|
||||||
|
val cte = statement.ctes.single()
|
||||||
|
assertEquals("recent", cte.name)
|
||||||
|
assertNull(cte.columns)
|
||||||
|
assertEquals("a", tableName(cte.query))
|
||||||
|
assertEquals("recent", tableName(statement.body))
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun parsesWithRecursiveAndMultipleCtesWithColumnLists() {
|
||||||
|
val statement = parseOne(
|
||||||
|
"WITH RECURSIVE first_cte(x) AS (SELECT id FROM a), second_cte AS (SELECT id FROM b) SELECT x FROM first_cte"
|
||||||
|
) as WithQuery
|
||||||
|
assertEquals(true, statement.recursive)
|
||||||
|
assertEquals(2, statement.ctes.size)
|
||||||
|
assertEquals(listOf("x"), statement.ctes[0].columns)
|
||||||
|
assertNull(statement.ctes[1].columns)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun explainAcceptsAUnionQuery() {
|
||||||
|
val statement = parseOne("EXPLAIN SELECT id FROM a UNION SELECT id FROM b") as ExplainStatement
|
||||||
|
assertTrue(statement.select is SetOperationStatement)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun createViewAcceptsAUnionQuery() {
|
||||||
|
val statement = parseOne("CREATE VIEW v AS SELECT id FROM a UNION SELECT id FROM b") as CreateViewStatement
|
||||||
|
assertTrue(statement.query is SetOperationStatement)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun derivedTableAcceptsACompoundQuery() {
|
||||||
|
val statement = parseOne("SELECT * FROM (SELECT id FROM a UNION SELECT id FROM b) AS u") as SelectStatement
|
||||||
|
val from = statement.from as SubquerySource
|
||||||
|
assertTrue(from.select is SetOperationStatement)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun derivedTableAcceptsAWithQuery() {
|
||||||
|
val statement = parseOne("SELECT * FROM (WITH x AS (SELECT id FROM a) SELECT id FROM x) AS u") as SelectStatement
|
||||||
|
val from = statement.from as SubquerySource
|
||||||
|
assertTrue(from.select is WithQuery)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun parsesColumnLevelForeignKeyWithDefaultActions() {
|
||||||
|
val statement = parseOne(
|
||||||
|
"CREATE TABLE t (id INTEGER PRIMARY KEY, dept_id INTEGER REFERENCES departments(id))"
|
||||||
|
) as CreateTableStatement
|
||||||
|
val fk = statement.foreignKeys.single()
|
||||||
|
assertEquals(listOf("dept_id"), fk.columns)
|
||||||
|
assertEquals("departments", fk.referencedTable)
|
||||||
|
assertEquals(listOf("id"), fk.referencedColumns)
|
||||||
|
assertEquals(ForeignKeyAction.NoAction, fk.onDelete)
|
||||||
|
assertEquals(ForeignKeyAction.NoAction, fk.onUpdate)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun parsesForeignKeyActionsInEitherOrder() {
|
||||||
|
val cascade = parseOne(
|
||||||
|
"CREATE TABLE t (id INTEGER PRIMARY KEY, x INTEGER REFERENCES d(id) ON DELETE CASCADE ON UPDATE RESTRICT)"
|
||||||
|
) as CreateTableStatement
|
||||||
|
val fk1 = cascade.foreignKeys.single()
|
||||||
|
assertEquals(ForeignKeyAction.Cascade, fk1.onDelete)
|
||||||
|
assertEquals(ForeignKeyAction.Restrict, fk1.onUpdate)
|
||||||
|
|
||||||
|
val reordered = parseOne(
|
||||||
|
"CREATE TABLE t (id INTEGER PRIMARY KEY, x INTEGER REFERENCES d(id) ON UPDATE SET NULL ON DELETE NO ACTION)"
|
||||||
|
) as CreateTableStatement
|
||||||
|
val fk2 = reordered.foreignKeys.single()
|
||||||
|
assertEquals(ForeignKeyAction.NoAction, fk2.onDelete)
|
||||||
|
assertEquals(ForeignKeyAction.SetNull, fk2.onUpdate)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun parsesTableLevelForeignKeyConstraint() {
|
||||||
|
val statement = parseOne(
|
||||||
|
"CREATE TABLE t (id INTEGER PRIMARY KEY, dept_id INTEGER, FOREIGN KEY (dept_id) REFERENCES departments(id))"
|
||||||
|
) as CreateTableStatement
|
||||||
}
|
}
|
||||||
Reference in new issue
Block a user