You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
We have a table with a custom type in a set column. This custom type was altered. One optional column was added. Cqlsh and native Cassandra driver works fine in that case. Result sets for rows inserted before ALTER TYPE returns null for a new column.
However, phantom throws BufferUnderflowException for such rows. Rows inserted after ALTER TYPE works correctly.
Stack trace:
com.datastax.driver.core.exceptions.InvalidTypeException:Not enough bytes to deserialize a tuple
at xyz.Entities$$anon$1.deserialize(Test.scala:17)
at xyz.Entities$$anon$1.deserialize(Test.scala:17)
at com.outworkers.phantom.builder.primitives.Primitive$$anon$6.deserialize(Primitive.scala:651)
at com.outworkers.phantom.builder.primitives.Primitives$$anon$1.$anonfun$deserialize$1(Primitives.scala:155)
at com.outworkers.phantom.builder.primitives.Primitives$$anon$1.$anonfun$deserialize$1$adapted(Primitives.scala:153)
at scala.collection.immutable.Range.foreach(Range.scala:158)
at com.outworkers.phantom.builder.primitives.Primitives$$anon$1.deserialize(Primitives.scala:153)
at com.outworkers.phantom.builder.primitives.Primitives$$anon$1.deserialize(Primitives.scala:120)
at com.outworkers.phantom.builder.primitives.Primitive.$anonfun$fromRow$1(Primitive.scala:131)
at com.outworkers.phantom.builder.primitives.Primitive.$anonfun$nullCheck$4(Primitive.scala:105)
at scala.util.Try$.apply(Try.scala:213)
at com.outworkers.phantom.builder.primitives.Primitive.nullCheck(Primitive.scala:105)
at com.outworkers.phantom.builder.primitives.Primitive.fromRow(Primitive.scala:131)
at com.outworkers.phantom.column.PrimitiveColumn.parse(PrimitiveColumn.scala:38)
at com.outworkers.phantom.column.Column.apply(Column.scala:30)
at xyz.Entities$anon$macro$1$1.fromRow(Test.scala:22)
at xyz.Entities$anon$macro$1$1.fromRow(Test.scala:22)
at com.outworkers.phantom.CassandraTable.fromRow(CassandraTable.scala:65)
at com.outworkers.phantom.SelectTable.$anonfun$select$1(SelectTable.scala:26)
at com.outworkers.phantom.builder.query.SelectQuery.fromRow(SelectQuery.scala:58)
at com.outworkers.phantom.ops.SelectQueryOps.fromRow(SelectQueryOps.scala:100)
at com.outworkers.phantom.builder.query.execution.ResultQueryInterface.$anonfun$singleResult$1(ResultQueryInterface.scala:34)
at scala.Option.map(Option.scala:230)
at com.outworkers.phantom.builder.query.execution.ResultQueryInterface.singleResult(ResultQueryInterface.scala:34)
at com.outworkers.phantom.builder.query.execution.ResultQueryInterface.$anonfun$singleFetch$1(ResultQueryInterface.scala:57)
at scala.util.Success.$anonfun$map$1(Try.scala:255)
at scala.util.Success.map(Try.scala:213)
at scala.concurrent.Future.$anonfun$map$1(Future.scala:292)
at scala.concurrent.impl.Promise.liftedTree1$1(Promise.scala:33)
at scala.concurrent.impl.Promise.$anonfun$transform$1(Promise.scala:33)
at scala.concurrent.impl.CallbackRunnable.run(Promise.scala:64)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
at java.lang.Thread.run(Thread.java:748)
Cause: java.nio.BufferUnderflowException:
at java.nio.Buffer.nextGetIndex(Buffer.java:506)
at java.nio.HeapByteBuffer.getInt(HeapByteBuffer.java:361)
at xyz.Entities$$anon$1.$anonfun$deserialize$1(Test.scala:17)
at scala.Option.flatMap(Option.scala:271)
at xyz.Entities$$anon$1.deserialize(Test.scala:17)
at xyz.Entities$$anon$1.deserialize(Test.scala:17)
at com.outworkers.phantom.builder.primitives.Primitive$$anon$6.deserialize(Primitive.scala:651)
at com.outworkers.phantom.builder.primitives.Primitives$$anon$1.$anonfun$deserialize$1(Primitives.scala:155)
at com.outworkers.phantom.builder.primitives.Primitives$$anon$1.$anonfun$deserialize$1$adapted(Primitives.scala:153)
at scala.collection.immutable.Range.foreach(Range.scala:158)
at com.outworkers.phantom.builder.primitives.Primitives$$anon$1.deserialize(Primitives.scala:153)
at com.outworkers.phantom.builder.primitives.Primitives$$anon$1.deserialize(Primitives.scala:120)
at com.outworkers.phantom.builder.primitives.Primitive.$anonfun$fromRow$1(Primitive.scala:131)
at com.outworkers.phantom.builder.primitives.Primitive.$anonfun$nullCheck$4(Primitive.scala:105)
at scala.util.Try$.apply(Try.scala:213)
at com.outworkers.phantom.builder.primitives.Primitive.nullCheck(Primitive.scala:105)
at com.outworkers.phantom.builder.primitives.Primitive.fromRow(Primitive.scala:131)
at com.outworkers.phantom.column.PrimitiveColumn.parse(PrimitiveColumn.scala:38)
at com.outworkers.phantom.column.Column.apply(Column.scala:30)
at xyz.Entities$anon$macro$1$1.fromRow(Test.scala:22)
at xyz.Entities$anon$macro$1$1.fromRow(Test.scala:22)
at com.outworkers.phantom.CassandraTable.fromRow(CassandraTable.scala:65)
at com.outworkers.phantom.SelectTable.$anonfun$select$1(SelectTable.scala:26)
at com.outworkers.phantom.builder.query.SelectQuery.fromRow(SelectQuery.scala:58)
at com.outworkers.phantom.ops.SelectQueryOps.fromRow(SelectQueryOps.scala:100)
at com.outworkers.phantom.builder.query.execution.ResultQueryInterface.$anonfun$singleResult$1(ResultQueryInterface.scala:34)
at scala.Option.map(Option.scala:230)
at com.outworkers.phantom.builder.query.execution.ResultQueryInterface.singleResult(ResultQueryInterface.scala:34)
at com.outworkers.phantom.builder.query.execution.ResultQueryInterface.$anonfun$singleFetch$1(ResultQueryInterface.scala:57)
at scala.util.Success.$anonfun$map$1(Try.scala:255)
at scala.util.Success.map(Try.scala:213)
at scala.concurrent.Future.$anonfun$map$1(Future.scala:292)
at scala.concurrent.impl.Promise.liftedTree1$1(Promise.scala:33)
at scala.concurrent.impl.Promise.$anonfun$transform$1(Promise.scala:33)
at scala.concurrent.impl.CallbackRunnable.run(Promise.scala:64)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
at java.lang.Thread.run(Thread.java:748)
Here is the min example which throws above exception
packagecom.onzo.cassandra.repositoryimportcom.onzo.cassandra.CassandraSupportimportcom.outworkers.phantom.connectors.ContactPointimportcom.outworkers.phantom.dsl._importorg.scalatest.WordSpecimportscala.collection.JavaConverters._importscala.concurrent.Awaitimportscala.concurrent.duration._caseclassSomeCustomType(a: String, b: Option[String])
caseclassEntity(id: String, value: String, value2: Set[SomeCustomType])
objectEntities {
implicitvalcustomTypePrimitive=Primitive.derive[SomeCustomType, (String, Option[String])](
c => (c.a, c.b))(
SomeCustomType.tupled
)
}
importEntities._abstractclassEntitiesextendsTable[Entities, Entity] {
objectidextendsCol[String] withPartitionKeyobjectvalueextendsCol[String]
objectvalue2extendsCol[Set[SomeCustomType]]
}
classMyDb(overridevalconnector:CassandraConnection) extendsDatabase[MyDb](connector) {
objectentitiesextendsEntitieswithConnectordeffirstRow() = {
entities
.select
.one()
}
}
classTestextendsWordSpecwithCassandraSupport {
"UDT" should {
"work" in {
valconnection=ContactPoint.embedded.noHeartbeat.keySpace(keyspace)
valsession= connection.session
// Initial type and table definition
session.execute(s"CREATE TYPE ${keyspace}.some_custom_type (a text);")
session.execute(s"CREATE TABLE ${keyspace}.entities ( id text PRIMARY KEY, value text, value2 set<frozen<some_custom_type>>);")
// Insert before modifying some_custom_type
session.execute(s"INSERT INTO ${keyspace}.entities (id, value, value2) VALUES('test', 'abc', {{a: 'AAA'}});")
// Add column to some_custom_type
session.execute(s"ALTER TYPE ${keyspace}.some_custom_type ADD b text;")
//Query row using raw cassandra drivervalrawRow= session.execute(s"select * from ${keyspace}.entities limit 1").asScala.head
println(s"Raw row: $rawRow")
//Prints - Raw row: Row[test, abc, [{a:'AAA',b:NULL}]]valmyDb=newMyDb(connection)
valphantomRow=Await.result(myDb.firstRow(), 5.seconds)
//Below fails if insert is before alter type but works if insert is after alter type
println(s"Phantom row: $phantomRow")
// Expected result - Phantom row: Some(Entity(test,abc,Set(SomeCustomType(AAA,None))))
}
}
}
Issue 2.
When I change Col[Set[SomeCustomType]] to SetColumn[SomeCustomType] I don't even get a exception. Instead of that phantom produce an empty Set (Phantom row: Some(Entity(test,abc,Set()))). It is very dangerous because due to lack of proper exception, you may not notice any problems on production for months. While the returned data is incorrect.
The text was updated successfully, but these errors were encountered:
Hi,
I have two interesting and related issues.
Issue 1:
We have a table with a custom type in a set column. This custom type was altered. One optional column was added. Cqlsh and native Cassandra driver works fine in that case. Result sets for rows inserted before
ALTER TYPE
returns null for a new column.However, phantom throws BufferUnderflowException for such rows. Rows inserted after
ALTER TYPE
works correctly.Stack trace:
Here is the min example which throws above exception
Issue 2.
When I change
Col[Set[SomeCustomType]]
toSetColumn[SomeCustomType]
I don't even get a exception. Instead of that phantom produce an empty Set (Phantom row: Some(Entity(test,abc,Set()))
). It is very dangerous because due to lack of proper exception, you may not notice any problems on production for months. While the returned data is incorrect.The text was updated successfully, but these errors were encountered: