Skip to content

Commit 0a129ae

Browse files
committed
Placeholder for alter type compatibility checks
1 parent 15d9ed8 commit 0a129ae

File tree

5 files changed

+39
-3
lines changed

5 files changed

+39
-3
lines changed

Diff for: troy-schema/src/main/scala/troy/schema/Message.scala

+1
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ object Messages {
2020
case class ColumnAlreadyExists(t: TableName, c: Identifier) extends Message(s"Invalid column name $c because it conflicts with an existing column in table $t")
2121

2222
case class CannotDropPrimaryKeyPart(c: Identifier) extends Message(s"Cannot drop PRIMARY KEY part $c")
23+
case class IncompatibleAlterType(c: Identifier, ot: DataType, nt: DataType) extends Message(s"Cannot change $c from type $ot to type $nt: types are incompatible.")
2324

2425
case class PrimaryKeyNotDefined(t: TableName) extends Message(s"CREATE TABLE $t statement has no Primary key defined")
2526

Diff for: troy-schema/src/main/scala/troy/schema/SchemaEngine.scala

+2-1
Original file line numberDiff line numberDiff line change
@@ -188,7 +188,8 @@ case class SchemaEngineImpl(schema: Schema, context: Option[KeyspaceName]) exten
188188

189189
private val noVariables: Result[Seq[DataType]] = V.success(Seq.empty)
190190

191-
override def +(stmt: DataDefinition) = stmt match {
191+
override def +(stmt: DataDefinition) =
192+
validations.validate(stmt).map(_ => stmt) flatMap {
192193
case s: CreateKeyspace => schema.apply(s).map(s => copy(s))
193194
case s: CreateTable => schema.apply(enrichWithContext(s)).map(s => copy(s))
194195
case s: CreateIndex => schema.apply(enrichWithContext(s)).map(s => copy(s))
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
package troy.schema.validation
2+
3+
import troy.cql.ast._
4+
import troy.cql.ast.ddl.Alter.AlterType
5+
import troy.schema.{ V, Messages, Schema }
6+
7+
class AlterColumnIncompatibleTypes(schema: Schema) extends Validation[DataDefinition] {
8+
import DataType._
9+
override def rules = {
10+
case AlterTable(tableName, AlterType(columnName, newCqlType)) =>
11+
schema.getColumns(tableName, Seq(columnName)).map(_.head.dataType).flatMap { oldCqlType =>
12+
if (isCompatible(oldCqlType, newCqlType))
13+
noMessages
14+
else
15+
V.error(Messages.IncompatibleAlterType(columnName, oldCqlType, newCqlType))
16+
}
17+
}
18+
19+
def isCompatible(oldDT: DataType, newDT: DataType) = oldDT -> newDT match {
20+
case (_, Blob) => true
21+
// TODO
22+
case _ => oldDT == newDT
23+
}
24+
}

Diff for: troy-schema/src/main/scala/troy/schema/validation/Validation.scala

+8-2
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
package troy.schema.validation
22

3-
import troy.cql.ast.DataManipulation
3+
import troy.cql.ast.{ DataDefinition, DataManipulation }
44
import troy.schema._
55

66
trait Validation[-T] {
@@ -16,7 +16,9 @@ class Validations(schema: Schema, levelConfig: Message => Validations.Level) {
1616
def validate(statement: DataManipulation): Result[_] =
1717
validate(dmValidations, statement)
1818

19-
def adjustMessageLevels(msgs: Iterable[Message]) = {
19+
def validate(statement: DataDefinition): Result[_] =
20+
validate(ddValidations, statement)
21+
2022
protected[this] def validate[T](validations: Seq[Validation[T]], statement: T): Result[_] =
2123
V.merge(validations.map(_.validate(statement).flatMap(adjustMessageLevels)))
2224

@@ -38,6 +40,10 @@ class Validations(schema: Schema, levelConfig: Message => Validations.Level) {
3840
new WhereNonPrimaryNoIndex(schema)
3941
)
4042

43+
protected[this] val ddValidations = Seq(
44+
new AlterColumnIncompatibleTypes(schema)
45+
)
46+
4147
protected[this] val emptyResponse: Result[Unit] = V.success(())
4248
}
4349

Diff for: troy-schema/src/test/scala/troy/schema/AlterTableSpec.scala

+4
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,10 @@ class AlterTableSpec extends WordSpec with Matchers {
8282
.get(parseQuery("SELECT post_title from test.posts;")).get
8383
row.asInstanceOf[SchemaEngine.Columns].types shouldBe Seq(DataType.Blob)
8484
}
85+
86+
"refuse incompatible types" in {
87+
alter("ALTER TABLE test.posts ALTER author_name TYPE date;").getError shouldBe Messages.IncompatibleAlterType("author_name", DataType.Text, DataType.Date)
88+
}
8589
}
8690

8791
"adding options" should {

0 commit comments

Comments
 (0)