Skip to content

Commit 0136fc9

Browse files
Fix CQLSSTableWriter serialization of vector of date and time
patch by Lukasz Antoniak; reviewed by Andres de la Pena, Yifan Cai for CASSANDRA-20979
1 parent f894b84 commit 0136fc9

File tree

3 files changed

+85
-6
lines changed

3 files changed

+85
-6
lines changed

CHANGES.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
5.0.7
2+
* Fix CQLSSTableWriter serialization of vector of date and time (CASSANDRA-20979)
23
* Correctly calculate default for FailureDetector max interval (CASSANDRA-21025)
34
* Adding missing configs in system_views.settings to be backward compatible (CASSANDRA-20863)
45
* Heap dump should not be generated on handled exceptions (CASSANDRA-20974)

src/java/org/apache/cassandra/cql3/functions/types/TypeCodec.java

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1787,12 +1787,6 @@ private DateCodec()
17871787
super(DataType.date(), LocalDate.class);
17881788
}
17891789

1790-
@Override
1791-
public int serializedSize()
1792-
{
1793-
return 8;
1794-
}
1795-
17961790
@Override
17971791
public LocalDate parse(String value)
17981792
{
@@ -1876,6 +1870,13 @@ private TimeCodec()
18761870
super(DataType.time());
18771871
}
18781872

1873+
@Override
1874+
public int serializedSize()
1875+
{
1876+
// matching behavior of TimeType, which is not declared as fixed length
1877+
return VARIABLE_LENGTH;
1878+
}
1879+
18791880
@Override
18801881
public Long parse(String value)
18811882
{

test/unit/org/apache/cassandra/io/sstable/CQLSSTableWriterTest.java

Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,9 @@
3434
import java.util.UUID;
3535
import java.util.concurrent.TimeUnit;
3636
import java.util.concurrent.atomic.AtomicInteger;
37+
import java.util.function.BiConsumer;
3738
import java.util.function.BiPredicate;
39+
import java.util.function.Function;
3840
import java.util.stream.Collectors;
3941
import java.util.stream.Stream;
4042
import java.util.stream.StreamSupport;
@@ -49,6 +51,7 @@
4951

5052
import com.datastax.driver.core.utils.UUIDs;
5153
import org.apache.cassandra.Util;
54+
import org.apache.cassandra.cql3.CQL3Type;
5255
import org.apache.cassandra.cql3.QueryProcessor;
5356
import org.apache.cassandra.cql3.UntypedResultSet;
5457
import org.apache.cassandra.cql3.functions.types.DataType;
@@ -58,6 +61,10 @@
5861
import org.apache.cassandra.cql3.functions.types.UserType;
5962
import org.apache.cassandra.db.ColumnFamilyStore;
6063
import org.apache.cassandra.db.Keyspace;
64+
import org.apache.cassandra.db.marshal.AbstractType;
65+
import org.apache.cassandra.db.marshal.FloatType;
66+
import org.apache.cassandra.db.marshal.SimpleDateType;
67+
import org.apache.cassandra.db.marshal.TimeType;
6168
import org.apache.cassandra.db.marshal.UTF8Type;
6269
import org.apache.cassandra.dht.ByteOrderedPartitioner;
6370
import org.apache.cassandra.dht.Murmur3Partitioner;
@@ -76,6 +83,7 @@
7683
import org.apache.cassandra.utils.JavaDriverUtils;
7784

7885
import static org.apache.cassandra.utils.Clock.Global.currentTimeMillis;
86+
import static org.assertj.core.api.Assertions.assertThat;
7987
import static org.junit.Assert.assertEquals;
8088
import static org.junit.Assert.assertFalse;
8189
import static org.junit.Assert.assertNotNull;
@@ -1520,6 +1528,75 @@ public void testSkipBuildingIndexesWithSAI() throws Exception
15201528
assertFalse(indexDescriptor.isPerColumnIndexBuildComplete(new IndexIdentifier(keyspace, table, "idx2")));
15211529
}
15221530

1531+
@Test
1532+
public void testWritingVectorData() throws Exception
1533+
{
1534+
testWritingVectorData(CQL3Type.Native.FLOAT, FloatType.instance, (i) -> (float) i, (i, vector) -> {
1535+
assertThat(vector).allMatch(val -> val instanceof Float);
1536+
assertThat(vector).allMatch(val -> (float) val == (float) i);
1537+
});
1538+
1539+
perTestSetup();
1540+
1541+
testWritingVectorData(CQL3Type.Native.DATE, SimpleDateType.instance, LocalDate::fromDaysSinceEpoch, (i, vector) -> {
1542+
assertThat(vector).allMatch(val -> val instanceof Integer);
1543+
assertThat(vector).allMatch(val -> {
1544+
int days = (int) val - Integer.MIN_VALUE; // signed to unsigned conversion
1545+
return days == i;
1546+
});
1547+
});
1548+
1549+
perTestSetup();
1550+
1551+
testWritingVectorData(CQL3Type.Native.TIME, TimeType.instance, (i) -> (long) i, (i, vector) -> {
1552+
assertThat(vector).allMatch(val -> val instanceof Long);
1553+
assertThat(vector).allMatch(val -> (long) val == (long) i);
1554+
});
1555+
}
1556+
1557+
private void testWritingVectorData(CQL3Type.Native cqlType, AbstractType<?> subType, Function<Integer, ?> valueFactory,
1558+
BiConsumer<Integer, List<?>> checkFunction) throws Exception
1559+
{
1560+
final int dimensions = 5;
1561+
final String schema = "CREATE TABLE " + qualifiedTable + " ("
1562+
+ " k int,"
1563+
+ " v1 VECTOR<" + cqlType.name() + ", " + dimensions + ">,"
1564+
+ " PRIMARY KEY (k)"
1565+
+ ")";
1566+
1567+
CQLSSTableWriter writer = CQLSSTableWriter.builder()
1568+
.inDirectory(dataDir)
1569+
.forTable(schema)
1570+
.using("INSERT INTO " + keyspace + "." + table + " (k, v1) " +
1571+
"VALUES (?, ?)").build();
1572+
1573+
for (int i = 0; i < 100; i++)
1574+
{
1575+
List<Object> vector = new ArrayList<>(dimensions);
1576+
for (int j = 0; j < dimensions; j++)
1577+
{
1578+
vector.add(valueFactory.apply(i));
1579+
}
1580+
writer.addRow(i, vector);
1581+
}
1582+
1583+
writer.close();
1584+
loadSSTables(dataDir, keyspace);
1585+
1586+
UntypedResultSet resultSet = QueryProcessor.executeInternal("SELECT * FROM " + keyspace + "." + table);
1587+
1588+
assertEquals(resultSet.size(), 100);
1589+
int cnt = 0;
1590+
for (UntypedResultSet.Row row : resultSet)
1591+
{
1592+
assertEquals(cnt, row.getInt("k"));
1593+
List<?> vector = row.getVector("v1", subType, dimensions);
1594+
assertThat(vector).hasSize(dimensions);
1595+
checkFunction.accept(cnt, vector);
1596+
cnt++;
1597+
}
1598+
}
1599+
15231600
protected void loadSSTables(File dataDir, String ksName)
15241601
{
15251602
ColumnFamilyStore cfs = Keyspace.openWithoutSSTables(ksName).getColumnFamilyStore(table);

0 commit comments

Comments
 (0)