test: cover parsesColumnLevelAndTableLevelCheckConstraints
This commit is contained in:
1 parent
327e8f2431
commit
22f6ce2ed4
1 file changed
+173
@@ -1630,4 +1630,177 @@ class ParserTest {
|
||||
val statement = parseOne(
|
||||
"CREATE TABLE t (id INTEGER PRIMARY KEY, dept_id INTEGER, FOREIGN KEY (dept_id) REFERENCES departments(id))"
|
||||
) as CreateTableStatement
|
||||
assertEquals(2, statement.columns.size)
|
||||
val fk = statement.foreignKeys.single()
|
||||
assertEquals(listOf("dept_id"), fk.columns)
|
||||
assertEquals("departments", fk.referencedTable)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun parsesColumnLevelAndTableLevelCheckConstraints() {
|
||||
val statement = parseOne(
|
||||
"CREATE TABLE t (id INTEGER PRIMARY KEY, age INTEGER CHECK (age > 0), CHECK (id <> 0))"
|
||||
) as CreateTableStatement
|
||||
assertEquals(2, statement.checks.size)
|
||||
assertTrue(statement.checks[0].expression is BinaryExpression)
|
||||
assertTrue(statement.checks[1].expression is BinaryExpression)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun parsesColumnLevelUniqueConstraint() {
|
||||
val statement = parseOne(
|
||||
"CREATE TABLE t (id INTEGER PRIMARY KEY, email TEXT UNIQUE)"
|
||||
) as CreateTableStatement
|
||||
val unique = statement.uniqueConstraints.single()
|
||||
assertEquals(listOf("email"), unique.columns)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun parsesTableLevelCompositeUniqueConstraint() {
|
||||
val statement = parseOne(
|
||||
"CREATE TABLE t (a INTEGER, b INTEGER, c INTEGER, UNIQUE (a, b, c))"
|
||||
) as CreateTableStatement
|
||||
val unique = statement.uniqueConstraints.single()
|
||||
assertEquals(listOf("a", "b", "c"), unique.columns)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun parsesMultipleUniqueConstraintsMixingColumnAndTableLevel() {
|
||||
val statement = parseOne(
|
||||
"CREATE TABLE t (id INTEGER PRIMARY KEY, email TEXT UNIQUE, a INTEGER, b INTEGER, UNIQUE (a, b))"
|
||||
) as CreateTableStatement
|
||||
assertEquals(2, statement.uniqueConstraints.size)
|
||||
assertEquals(listOf("email"), statement.uniqueConstraints[0].columns)
|
||||
assertEquals(listOf("a", "b"), statement.uniqueConstraints[1].columns)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun parsesAlterTableAddColumnWithNotNullAndDefault() {
|
||||
val statement = parseOne("ALTER TABLE t ADD COLUMN active BOOLEAN NOT NULL DEFAULT TRUE") as AlterTableStatement
|
||||
assertEquals("t", statement.tableName)
|
||||
val action = statement.action as AddColumn
|
||||
assertEquals("active", action.column.name)
|
||||
assertEquals(ColumnType.Boolean, action.column.type)
|
||||
assertTrue(action.column.notNull)
|
||||
assertEquals(LiteralExpression(Value.BooleanValue(true)), action.column.default)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun parsesAlterTableAddColumnWithoutDefault() {
|
||||
val statement = parseOne("ALTER TABLE t ADD COLUMN note TEXT") as AlterTableStatement
|
||||
val action = statement.action as AddColumn
|
||||
assertEquals("note", action.column.name)
|
||||
assertFalse(action.column.notNull)
|
||||
assertNull(action.column.default)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun parsesAlterTableDropColumnWithAndWithoutCascade() {
|
||||
val plain = (parseOne("ALTER TABLE t DROP COLUMN note") as AlterTableStatement).action as DropColumn
|
||||
assertEquals("note", plain.columnName)
|
||||
assertEquals(DropMode.Restrict, plain.mode)
|
||||
val cascaded = (parseOne("ALTER TABLE t DROP COLUMN note CASCADE") as AlterTableStatement).action as DropColumn
|
||||
assertEquals(DropMode.Cascade, cascaded.mode)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun parsesAlterTableRenameColumn() {
|
||||
val action = (parseOne("ALTER TABLE t RENAME COLUMN a TO b") as AlterTableStatement).action as RenameColumn
|
||||
assertEquals("a", action.oldName)
|
||||
assertEquals("b", action.newName)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun parsesAlterTableRenameTo() {
|
||||
val statement = parseOne("ALTER TABLE t RENAME TO t2") as AlterTableStatement
|
||||
assertEquals("t", statement.tableName)
|
||||
val action = statement.action as RenameTable
|
||||
assertEquals("t2", action.newName)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun parsesAlterTableAlterColumnTypeWithColumnKeywordAndUsing() {
|
||||
val action = (parseOne("ALTER TABLE t ALTER COLUMN amount TYPE DECIMAL(10, 2) USING amount") as AlterTableStatement)
|
||||
.action as ChangeColumnType
|
||||
assertEquals("amount", action.columnName)
|
||||
assertEquals(ColumnType.Decimal, action.newType)
|
||||
assertEquals(10, action.precision)
|
||||
assertEquals(2, action.scale)
|
||||
assertEquals(ColumnExpression("amount"), action.using)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun parsesAlterTableAlterColumnTypeWithoutColumnKeywordOrUsing() {
|
||||
val action = (parseOne("ALTER TABLE t ALTER amount TYPE REAL") as AlterTableStatement).action as ChangeColumnType
|
||||
assertEquals("amount", action.columnName)
|
||||
assertEquals(ColumnType.Real, action.newType)
|
||||
assertNull(action.precision)
|
||||
assertNull(action.using)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun alterTableAlterColumnRejectsAMissingTypeKeyword() {
|
||||
assertFailsWith<ParseException> { parse("ALTER TABLE t ALTER COLUMN amount REAL") }
|
||||
}
|
||||
|
||||
@Test
|
||||
fun alterTableAddColumnRejectsPrimaryKeyReferencesUniqueAndCheck() {
|
||||
assertFailsWith<ParseException> { parse("ALTER TABLE t ADD COLUMN id INTEGER PRIMARY KEY") }
|
||||
assertFailsWith<ParseException> { parse("ALTER TABLE t ADD COLUMN dept_id INTEGER REFERENCES departments(id)") }
|
||||
assertFailsWith<ParseException> { parse("ALTER TABLE t ADD COLUMN email TEXT UNIQUE") }
|
||||
assertFailsWith<ParseException> { parse("ALTER TABLE t ADD COLUMN age INTEGER CHECK (age > 0)") }
|
||||
}
|
||||
|
||||
@Test
|
||||
fun parsesColumnLevelDefaultInCreateTable() {
|
||||
val statement = parseOne("CREATE TABLE t (id INTEGER PRIMARY KEY, status TEXT DEFAULT 'new')") as CreateTableStatement
|
||||
assertEquals(LiteralExpression(Value.TextValue("new")), statement.columns[1].default)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun parsesGeneratedAlwaysAsStoredInCreateTable() {
|
||||
val statement = parseOne("CREATE TABLE t (a INTEGER, b INTEGER GENERATED ALWAYS AS (a * 2) STORED)") as CreateTableStatement
|
||||
assertEquals(null, statement.columns[0].generated)
|
||||
assertEquals(
|
||||
BinaryExpression(BinaryOperator.Multiply, ColumnExpression("a"), LiteralExpression(Value.IntegerValue(2))),
|
||||
statement.columns[1].generated
|
||||
)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun generatedColumnRequiresAlwaysKeyword() {
|
||||
assertFailsWith<ParseException> { parse("CREATE TABLE t (a INTEGER, b INTEGER GENERATED AS (a) STORED)") }
|
||||
}
|
||||
|
||||
@Test
|
||||
fun generatedColumnRequiresAsKeyword() {
|
||||
assertFailsWith<ParseException> { parse("CREATE TABLE t (a INTEGER, b INTEGER GENERATED ALWAYS (a) STORED)") }
|
||||
}
|
||||
|
||||
@Test
|
||||
fun generatedColumnRequiresStoredKeyword() {
|
||||
assertFailsWith<ParseException> { parse("CREATE TABLE t (a INTEGER, b INTEGER GENERATED ALWAYS AS (a))") }
|
||||
}
|
||||
|
||||
@Test
|
||||
fun generatedColumnRejectsCombiningWithDefault() {
|
||||
assertFailsWith<ParseException> { parse("CREATE TABLE t (a INTEGER, b INTEGER DEFAULT 1 GENERATED ALWAYS AS (a) STORED)") }
|
||||
}
|
||||
|
||||
@Test
|
||||
fun generatedColumnRejectsCombiningWithPrimaryKey() {
|
||||
assertFailsWith<ParseException> {
|
||||
parse("CREATE TABLE t (a INTEGER, b INTEGER GENERATED ALWAYS AS (a) STORED PRIMARY KEY)")
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun generatedIsAContextualKeywordUsableAsAColumnName() {
|
||||
val statement = parseOne("CREATE TABLE t (generated INTEGER, always INTEGER, stored INTEGER)") as CreateTableStatement
|
||||
assertEquals(listOf("generated", "always", "stored"), statement.columns.map { it.name })
|
||||
}
|
||||
|
||||
@Test
|
||||
fun parsesGeneratedAlwaysAsStoredInAlterTableAddColumn() {
|
||||
val statement = parseOne("ALTER TABLE t ADD COLUMN b INTEGER GENERATED ALWAYS AS (a * 2) STORED") as AlterTableStatement
|
||||
}
|
||||
Reference in new issue
Block a user