From 9e870339a3e587978f5d532534fa568c8676978f Mon Sep 17 00:00:00 2001 From: janehe Date: Thu, 2 May 2024 08:16:32 -0700 Subject: [PATCH 01/24] INSERT and DELETE working --- .../api/querybuilder/delete/DeleteSelectorTest.java | 8 ++++++++ .../driver/api/querybuilder/insert/RegularInsertTest.java | 8 ++++++++ 2 files changed, 16 insertions(+) diff --git a/query-builder/src/test/java/com/datastax/oss/driver/api/querybuilder/delete/DeleteSelectorTest.java b/query-builder/src/test/java/com/datastax/oss/driver/api/querybuilder/delete/DeleteSelectorTest.java index 23210971bc6..d8a22a14c36 100644 --- a/query-builder/src/test/java/com/datastax/oss/driver/api/querybuilder/delete/DeleteSelectorTest.java +++ b/query-builder/src/test/java/com/datastax/oss/driver/api/querybuilder/delete/DeleteSelectorTest.java @@ -24,6 +24,8 @@ import org.junit.Test; +import java.util.Arrays; + public class DeleteSelectorTest { @Test @@ -34,6 +36,12 @@ public void should_generate_column_deletion() { .hasCql("DELETE v FROM ks.foo WHERE k=?"); } + @Test + public void should_generate_vector_deletion() { + assertThat(deleteFrom("foo").column("v").whereColumn("k").isEqualTo(literal(Arrays.asList(0.1, 0.2)))) + .hasCql("DELETE v FROM foo WHERE k=[0.1,0.2]"); + } + @Test public void should_generate_field_deletion() { assertThat( diff --git a/query-builder/src/test/java/com/datastax/oss/driver/api/querybuilder/insert/RegularInsertTest.java b/query-builder/src/test/java/com/datastax/oss/driver/api/querybuilder/insert/RegularInsertTest.java index 36133445b34..c22b87dd7e1 100644 --- a/query-builder/src/test/java/com/datastax/oss/driver/api/querybuilder/insert/RegularInsertTest.java +++ b/query-builder/src/test/java/com/datastax/oss/driver/api/querybuilder/insert/RegularInsertTest.java @@ -26,6 +26,8 @@ import com.datastax.oss.driver.api.querybuilder.term.Term; import com.datastax.oss.driver.internal.querybuilder.insert.DefaultInsert; import com.datastax.oss.driver.shaded.guava.common.collect.ImmutableMap; + +import java.util.Arrays; import java.util.Map; import org.junit.Test; @@ -41,6 +43,12 @@ public void should_generate_column_assignments() { .hasCql("INSERT INTO foo (a,b) VALUES (?,?)"); } + @Test + public void should_generate_vector_literals() { + assertThat(insertInto("foo").value("a", literal(Arrays.asList(0.1, 0.2, 0.3)))) + .hasCql("INSERT INTO foo (a) VALUES ([0.1,0.2,0.3])"); + } + @Test public void should_keep_last_assignment_if_column_listed_twice() { assertThat( From 9ea8689dd5ca8e3189dbb7d24ef2c160c88855dd Mon Sep 17 00:00:00 2001 From: janehe Date: Mon, 6 May 2024 12:10:48 -0700 Subject: [PATCH 02/24] orderBy(annOf("c1", CqlVector.newInstance(0.1, 0.2, 0.3)))) --- .../driver/api/querybuilder/QueryBuilder.java | 11 ++++ .../driver/api/querybuilder/select/Ann.java | 8 +++ .../api/querybuilder/select/Select.java | 2 + .../querybuilder/select/DefaultAnn.java | 58 +++++++++++++++++ .../querybuilder/select/DefaultSelect.java | 62 ++++++++++++++++--- .../select/SelectOrderingTest.java | 21 +++++++ 6 files changed, 154 insertions(+), 8 deletions(-) create mode 100644 query-builder/src/main/java/com/datastax/oss/driver/api/querybuilder/select/Ann.java create mode 100644 query-builder/src/main/java/com/datastax/oss/driver/internal/querybuilder/select/DefaultAnn.java diff --git a/query-builder/src/main/java/com/datastax/oss/driver/api/querybuilder/QueryBuilder.java b/query-builder/src/main/java/com/datastax/oss/driver/api/querybuilder/QueryBuilder.java index 8df2b7efdd0..ff5608e848a 100644 --- a/query-builder/src/main/java/com/datastax/oss/driver/api/querybuilder/QueryBuilder.java +++ b/query-builder/src/main/java/com/datastax/oss/driver/api/querybuilder/QueryBuilder.java @@ -19,6 +19,7 @@ import com.datastax.oss.driver.api.core.CqlIdentifier; import com.datastax.oss.driver.api.core.context.DriverContext; +import com.datastax.oss.driver.api.core.data.CqlVector; import com.datastax.oss.driver.api.core.metadata.token.Token; import com.datastax.oss.driver.api.core.type.DataType; import com.datastax.oss.driver.api.core.type.DataTypes; @@ -29,6 +30,7 @@ import com.datastax.oss.driver.api.querybuilder.delete.DeleteSelection; import com.datastax.oss.driver.api.querybuilder.insert.InsertInto; import com.datastax.oss.driver.api.querybuilder.relation.Relation; +import com.datastax.oss.driver.api.querybuilder.select.Ann; import com.datastax.oss.driver.api.querybuilder.select.SelectFrom; import com.datastax.oss.driver.api.querybuilder.select.Selector; import com.datastax.oss.driver.api.querybuilder.term.Term; @@ -43,6 +45,7 @@ import com.datastax.oss.driver.internal.querybuilder.DefaultRaw; import com.datastax.oss.driver.internal.querybuilder.delete.DefaultDelete; import com.datastax.oss.driver.internal.querybuilder.insert.DefaultInsert; +import com.datastax.oss.driver.internal.querybuilder.select.DefaultAnn; import com.datastax.oss.driver.internal.querybuilder.select.DefaultBindMarker; import com.datastax.oss.driver.internal.querybuilder.select.DefaultSelect; import com.datastax.oss.driver.internal.querybuilder.term.BinaryArithmeticTerm; @@ -538,4 +541,12 @@ public static Truncate truncate(@Nullable String keyspace, @NonNull String table return truncate( keyspace == null ? null : CqlIdentifier.fromCql(keyspace), CqlIdentifier.fromCql(table)); } + + public static Ann annOf(@NonNull CqlIdentifier cqlIdentifier, @NonNull CqlVector vector) { + return new DefaultAnn(cqlIdentifier, vector); + } + + public static Ann annOf(@NonNull String cqlIdentifier, @NonNull CqlVector vector) { + return new DefaultAnn(CqlIdentifier.fromCql(cqlIdentifier), vector); + } } diff --git a/query-builder/src/main/java/com/datastax/oss/driver/api/querybuilder/select/Ann.java b/query-builder/src/main/java/com/datastax/oss/driver/api/querybuilder/select/Ann.java new file mode 100644 index 00000000000..0423d675fd5 --- /dev/null +++ b/query-builder/src/main/java/com/datastax/oss/driver/api/querybuilder/select/Ann.java @@ -0,0 +1,8 @@ +package com.datastax.oss.driver.api.querybuilder.select; + +import com.datastax.oss.driver.api.core.data.CqlVector; +import com.datastax.oss.driver.api.querybuilder.BuildableQuery; + +public interface Ann extends BuildableQuery { + +} diff --git a/query-builder/src/main/java/com/datastax/oss/driver/api/querybuilder/select/Select.java b/query-builder/src/main/java/com/datastax/oss/driver/api/querybuilder/select/Select.java index a22b45c35bd..f0b5e744383 100644 --- a/query-builder/src/main/java/com/datastax/oss/driver/api/querybuilder/select/Select.java +++ b/query-builder/src/main/java/com/datastax/oss/driver/api/querybuilder/select/Select.java @@ -146,6 +146,8 @@ default Select orderBy(@NonNull String columnName, @NonNull ClusteringOrder orde return orderBy(CqlIdentifier.fromCql(columnName), order); } + @NonNull + Select orderBy(@NonNull Ann ann); /** * Adds a LIMIT clause to this query with a literal value. * diff --git a/query-builder/src/main/java/com/datastax/oss/driver/internal/querybuilder/select/DefaultAnn.java b/query-builder/src/main/java/com/datastax/oss/driver/internal/querybuilder/select/DefaultAnn.java new file mode 100644 index 00000000000..05ca97352eb --- /dev/null +++ b/query-builder/src/main/java/com/datastax/oss/driver/internal/querybuilder/select/DefaultAnn.java @@ -0,0 +1,58 @@ +package com.datastax.oss.driver.internal.querybuilder.select; + +import com.datastax.oss.driver.api.core.CqlIdentifier; +import com.datastax.oss.driver.api.core.cql.SimpleStatement; +import com.datastax.oss.driver.api.core.cql.SimpleStatementBuilder; +import com.datastax.oss.driver.api.core.data.CqlVector; +import com.datastax.oss.driver.api.querybuilder.select.Ann; +import edu.umd.cs.findbugs.annotations.NonNull; + +import java.util.Map; + +import static com.datastax.oss.driver.api.querybuilder.QueryBuilder.literal; + +public class DefaultAnn implements Ann { + private final CqlIdentifier cqlIdentifier; + private final CqlVector vector; + + public DefaultAnn(@NonNull CqlIdentifier cqlIdentifier, @NonNull CqlVector vector) { + this.cqlIdentifier = cqlIdentifier; + this.vector = vector; + } + + @NonNull + @Override + public String asCql() { + StringBuilder builder = new StringBuilder(); + builder.append("ORDER BY "); + builder.append(this.cqlIdentifier.asCql(true)); + builder.append(" ANN OF "); + literal(vector).appendTo(builder); + return builder.toString(); + } + + @NonNull + @Override + public SimpleStatement build() { + return Ann.super.build(); + } + + @NonNull + @Override + public SimpleStatement build(@NonNull Object... values) { + return Ann.super.build(values); + } + + @NonNull + @Override + public SimpleStatement build(@NonNull Map namedValues) { + return Ann.super.build(namedValues); + } + + @NonNull + @Override + public SimpleStatementBuilder builder() { + return Ann.super.builder(); + } + +} diff --git a/query-builder/src/main/java/com/datastax/oss/driver/internal/querybuilder/select/DefaultSelect.java b/query-builder/src/main/java/com/datastax/oss/driver/internal/querybuilder/select/DefaultSelect.java index 86a2a07a3f2..4519385a762 100644 --- a/query-builder/src/main/java/com/datastax/oss/driver/internal/querybuilder/select/DefaultSelect.java +++ b/query-builder/src/main/java/com/datastax/oss/driver/internal/querybuilder/select/DefaultSelect.java @@ -23,6 +23,7 @@ import com.datastax.oss.driver.api.core.metadata.schema.ClusteringOrder; import com.datastax.oss.driver.api.querybuilder.BindMarker; import com.datastax.oss.driver.api.querybuilder.relation.Relation; +import com.datastax.oss.driver.api.querybuilder.select.Ann; import com.datastax.oss.driver.api.querybuilder.select.Select; import com.datastax.oss.driver.api.querybuilder.select.SelectFrom; import com.datastax.oss.driver.api.querybuilder.select.Selector; @@ -49,6 +50,7 @@ public class DefaultSelect implements SelectFrom, Select { private final ImmutableList relations; private final ImmutableList groupByClauses; private final ImmutableMap orderings; + private final Ann ann; private final Object limit; private final Object perPartitionLimit; private final boolean allowsFiltering; @@ -65,6 +67,7 @@ public DefaultSelect(@Nullable CqlIdentifier keyspace, @NonNull CqlIdentifier ta ImmutableMap.of(), null, null, + null, false); } @@ -74,6 +77,7 @@ public DefaultSelect(@Nullable CqlIdentifier keyspace, @NonNull CqlIdentifier ta * @param selectors if it contains {@link AllSelector#INSTANCE}, that must be the only element. * This isn't re-checked because methods that call this constructor internally already do it, * make sure you do it yourself. + * @param ann Approximate nearest neighbor. ANN ordering does not support secondary ordering or ASC order. */ public DefaultSelect( @Nullable CqlIdentifier keyspace, @@ -84,6 +88,7 @@ public DefaultSelect( @NonNull ImmutableList relations, @NonNull ImmutableList groupByClauses, @NonNull ImmutableMap orderings, + @Nullable Ann ann, @Nullable Object limit, @Nullable Object perPartitionLimit, boolean allowsFiltering) { @@ -94,6 +99,10 @@ public DefaultSelect( || (limit instanceof Integer && (Integer) limit > 0) || limit instanceof BindMarker, "limit must be a strictly positive integer or a bind marker"); + Preconditions.checkArgument( + orderings.isEmpty() || ann == null, + "ANN ordering does not support secondary ordering"); + this.ann = ann; this.keyspace = keyspace; this.table = table; this.isJson = isJson; @@ -117,6 +126,7 @@ public SelectFrom json() { relations, groupByClauses, orderings, + null, limit, perPartitionLimit, allowsFiltering); @@ -134,6 +144,7 @@ public SelectFrom distinct() { relations, groupByClauses, orderings, + null, limit, perPartitionLimit, allowsFiltering); @@ -193,6 +204,7 @@ public Select withSelectors(@NonNull ImmutableList newSelectors) { relations, groupByClauses, orderings, + null, limit, perPartitionLimit, allowsFiltering); @@ -221,6 +233,7 @@ public Select withRelations(@NonNull ImmutableList newRelations) { newRelations, groupByClauses, orderings, + null, limit, perPartitionLimit, allowsFiltering); @@ -249,6 +262,7 @@ public Select withGroupByClauses(@NonNull ImmutableList newGroupByClau relations, newGroupByClauses, orderings, + null, limit, perPartitionLimit, allowsFiltering); @@ -266,6 +280,12 @@ public Select orderByIds(@NonNull Map newOrderin return withOrderings(ImmutableCollections.concat(orderings, newOrderings)); } + @NonNull + @Override + public Select orderBy(@NonNull Ann ann){ + return withAnn(ann); + } + @NonNull public Select withOrderings(@NonNull ImmutableMap newOrderings) { return new DefaultSelect( @@ -277,6 +297,23 @@ public Select withOrderings(@NonNull ImmutableMap entry : orderings.entrySet()) { - if (first) { - builder.append(" ORDER BY "); - first = false; - } else { - builder.append(","); + if (ann != null){ + builder.append(" ").append(this.ann.asCql()); + }else{ + boolean first = true; + for (Map.Entry entry : orderings.entrySet()) { + if (first) { + builder.append(" ORDER BY "); + first = false; + } else { + builder.append(","); + } + builder.append(entry.getKey().asCql(true)).append(" ").append(entry.getValue().name()); } - builder.append(entry.getKey().asCql(true)).append(" ").append(entry.getValue().name()); } if (limit != null) { diff --git a/query-builder/src/test/java/com/datastax/oss/driver/api/querybuilder/select/SelectOrderingTest.java b/query-builder/src/test/java/com/datastax/oss/driver/api/querybuilder/select/SelectOrderingTest.java index ff27fde4f8f..437a705b62e 100644 --- a/query-builder/src/test/java/com/datastax/oss/driver/api/querybuilder/select/SelectOrderingTest.java +++ b/query-builder/src/test/java/com/datastax/oss/driver/api/querybuilder/select/SelectOrderingTest.java @@ -20,9 +20,11 @@ import static com.datastax.oss.driver.api.core.metadata.schema.ClusteringOrder.ASC; import static com.datastax.oss.driver.api.core.metadata.schema.ClusteringOrder.DESC; import static com.datastax.oss.driver.api.querybuilder.Assertions.assertThat; +import static com.datastax.oss.driver.api.querybuilder.QueryBuilder.annOf; import static com.datastax.oss.driver.api.querybuilder.QueryBuilder.literal; import static com.datastax.oss.driver.api.querybuilder.QueryBuilder.selectFrom; +import com.datastax.oss.driver.api.core.data.CqlVector; import com.datastax.oss.driver.api.querybuilder.relation.Relation; import com.datastax.oss.driver.shaded.guava.common.collect.ImmutableMap; import org.junit.Test; @@ -74,4 +76,23 @@ public void should_replace_previous_ordering() { .orderBy(ImmutableMap.of("c1", DESC, "c2", ASC))) .hasCql("SELECT * FROM foo WHERE k=1 ORDER BY c3 ASC,c1 DESC,c2 ASC"); } + + @Test + public void should_generate_ann_clause() { + assertThat( + selectFrom("foo") + .all() + .where(Relation.column("k").isEqualTo(literal(1))) + .orderBy(annOf("c1", CqlVector.newInstance(0.1, 0.2, 0.3)))) + .hasCql("SELECT * FROM foo WHERE k=1 ORDER BY c1 ANN OF [0.1, 0.2, 0.3]"); + } + + @Test(expected = IllegalArgumentException.class) + public void should_fail_when_provided_ann_with_other_orderings(){ + selectFrom("foo") + .all() + .where(Relation.column("k").isEqualTo(literal(1))) + .orderBy("c1", ASC) + .orderBy(annOf("c1", CqlVector.newInstance(0.1, 0.2, 0.3))); + } } From b035763082f89a28fcd8c67b2fd18dcdfd6d5952 Mon Sep 17 00:00:00 2001 From: janehe Date: Mon, 6 May 2024 12:18:15 -0700 Subject: [PATCH 03/24] fmt --- .../driver/api/querybuilder/select/Ann.java | 22 +++- .../querybuilder/select/DefaultAnn.java | 105 ++++++++++-------- .../querybuilder/select/DefaultSelect.java | 15 +-- .../delete/DeleteSelectorTest.java | 9 +- .../insert/RegularInsertTest.java | 1 - .../select/SelectOrderingTest.java | 10 +- 6 files changed, 97 insertions(+), 65 deletions(-) diff --git a/query-builder/src/main/java/com/datastax/oss/driver/api/querybuilder/select/Ann.java b/query-builder/src/main/java/com/datastax/oss/driver/api/querybuilder/select/Ann.java index 0423d675fd5..d287fc6e8fe 100644 --- a/query-builder/src/main/java/com/datastax/oss/driver/api/querybuilder/select/Ann.java +++ b/query-builder/src/main/java/com/datastax/oss/driver/api/querybuilder/select/Ann.java @@ -1,8 +1,22 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ package com.datastax.oss.driver.api.querybuilder.select; -import com.datastax.oss.driver.api.core.data.CqlVector; import com.datastax.oss.driver.api.querybuilder.BuildableQuery; -public interface Ann extends BuildableQuery { - -} +public interface Ann extends BuildableQuery {} diff --git a/query-builder/src/main/java/com/datastax/oss/driver/internal/querybuilder/select/DefaultAnn.java b/query-builder/src/main/java/com/datastax/oss/driver/internal/querybuilder/select/DefaultAnn.java index 05ca97352eb..6510f5dfbd3 100644 --- a/query-builder/src/main/java/com/datastax/oss/driver/internal/querybuilder/select/DefaultAnn.java +++ b/query-builder/src/main/java/com/datastax/oss/driver/internal/querybuilder/select/DefaultAnn.java @@ -1,58 +1,73 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ package com.datastax.oss.driver.internal.querybuilder.select; +import static com.datastax.oss.driver.api.querybuilder.QueryBuilder.literal; + import com.datastax.oss.driver.api.core.CqlIdentifier; import com.datastax.oss.driver.api.core.cql.SimpleStatement; import com.datastax.oss.driver.api.core.cql.SimpleStatementBuilder; import com.datastax.oss.driver.api.core.data.CqlVector; import com.datastax.oss.driver.api.querybuilder.select.Ann; import edu.umd.cs.findbugs.annotations.NonNull; - import java.util.Map; -import static com.datastax.oss.driver.api.querybuilder.QueryBuilder.literal; - public class DefaultAnn implements Ann { - private final CqlIdentifier cqlIdentifier; - private final CqlVector vector; - - public DefaultAnn(@NonNull CqlIdentifier cqlIdentifier, @NonNull CqlVector vector) { - this.cqlIdentifier = cqlIdentifier; - this.vector = vector; - } - - @NonNull - @Override - public String asCql() { - StringBuilder builder = new StringBuilder(); - builder.append("ORDER BY "); - builder.append(this.cqlIdentifier.asCql(true)); - builder.append(" ANN OF "); - literal(vector).appendTo(builder); - return builder.toString(); - } - - @NonNull - @Override - public SimpleStatement build() { - return Ann.super.build(); - } - - @NonNull - @Override - public SimpleStatement build(@NonNull Object... values) { - return Ann.super.build(values); - } - - @NonNull - @Override - public SimpleStatement build(@NonNull Map namedValues) { - return Ann.super.build(namedValues); - } - - @NonNull - @Override - public SimpleStatementBuilder builder() { - return Ann.super.builder(); - } + private final CqlIdentifier cqlIdentifier; + private final CqlVector vector; + + public DefaultAnn(@NonNull CqlIdentifier cqlIdentifier, @NonNull CqlVector vector) { + this.cqlIdentifier = cqlIdentifier; + this.vector = vector; + } + + @NonNull + @Override + public String asCql() { + StringBuilder builder = new StringBuilder(); + builder.append("ORDER BY "); + builder.append(this.cqlIdentifier.asCql(true)); + builder.append(" ANN OF "); + literal(vector).appendTo(builder); + return builder.toString(); + } + + @NonNull + @Override + public SimpleStatement build() { + return Ann.super.build(); + } + + @NonNull + @Override + public SimpleStatement build(@NonNull Object... values) { + return Ann.super.build(values); + } + + @NonNull + @Override + public SimpleStatement build(@NonNull Map namedValues) { + return Ann.super.build(namedValues); + } + @NonNull + @Override + public SimpleStatementBuilder builder() { + return Ann.super.builder(); + } } diff --git a/query-builder/src/main/java/com/datastax/oss/driver/internal/querybuilder/select/DefaultSelect.java b/query-builder/src/main/java/com/datastax/oss/driver/internal/querybuilder/select/DefaultSelect.java index 4519385a762..a45a515a62f 100644 --- a/query-builder/src/main/java/com/datastax/oss/driver/internal/querybuilder/select/DefaultSelect.java +++ b/query-builder/src/main/java/com/datastax/oss/driver/internal/querybuilder/select/DefaultSelect.java @@ -77,7 +77,8 @@ public DefaultSelect(@Nullable CqlIdentifier keyspace, @NonNull CqlIdentifier ta * @param selectors if it contains {@link AllSelector#INSTANCE}, that must be the only element. * This isn't re-checked because methods that call this constructor internally already do it, * make sure you do it yourself. - * @param ann Approximate nearest neighbor. ANN ordering does not support secondary ordering or ASC order. + * @param ann Approximate nearest neighbor. ANN ordering does not support secondary ordering or + * ASC order. */ public DefaultSelect( @Nullable CqlIdentifier keyspace, @@ -100,8 +101,7 @@ public DefaultSelect( || limit instanceof BindMarker, "limit must be a strictly positive integer or a bind marker"); Preconditions.checkArgument( - orderings.isEmpty() || ann == null, - "ANN ordering does not support secondary ordering"); + orderings.isEmpty() || ann == null, "ANN ordering does not support secondary ordering"); this.ann = ann; this.keyspace = keyspace; this.table = table; @@ -282,7 +282,7 @@ public Select orderByIds(@NonNull Map newOrderin @NonNull @Override - public Select orderBy(@NonNull Ann ann){ + public Select orderBy(@NonNull Ann ann) { return withAnn(ann); } @@ -303,7 +303,8 @@ public Select withOrderings(@NonNull ImmutableMap entry : orderings.entrySet()) { if (first) { diff --git a/query-builder/src/test/java/com/datastax/oss/driver/api/querybuilder/delete/DeleteSelectorTest.java b/query-builder/src/test/java/com/datastax/oss/driver/api/querybuilder/delete/DeleteSelectorTest.java index d8a22a14c36..77c2c543cf2 100644 --- a/query-builder/src/test/java/com/datastax/oss/driver/api/querybuilder/delete/DeleteSelectorTest.java +++ b/query-builder/src/test/java/com/datastax/oss/driver/api/querybuilder/delete/DeleteSelectorTest.java @@ -22,9 +22,8 @@ import static com.datastax.oss.driver.api.querybuilder.QueryBuilder.deleteFrom; import static com.datastax.oss.driver.api.querybuilder.QueryBuilder.literal; -import org.junit.Test; - import java.util.Arrays; +import org.junit.Test; public class DeleteSelectorTest { @@ -38,7 +37,11 @@ public void should_generate_column_deletion() { @Test public void should_generate_vector_deletion() { - assertThat(deleteFrom("foo").column("v").whereColumn("k").isEqualTo(literal(Arrays.asList(0.1, 0.2)))) + assertThat( + deleteFrom("foo") + .column("v") + .whereColumn("k") + .isEqualTo(literal(Arrays.asList(0.1, 0.2)))) .hasCql("DELETE v FROM foo WHERE k=[0.1,0.2]"); } diff --git a/query-builder/src/test/java/com/datastax/oss/driver/api/querybuilder/insert/RegularInsertTest.java b/query-builder/src/test/java/com/datastax/oss/driver/api/querybuilder/insert/RegularInsertTest.java index c22b87dd7e1..a277b037fc8 100644 --- a/query-builder/src/test/java/com/datastax/oss/driver/api/querybuilder/insert/RegularInsertTest.java +++ b/query-builder/src/test/java/com/datastax/oss/driver/api/querybuilder/insert/RegularInsertTest.java @@ -26,7 +26,6 @@ import com.datastax.oss.driver.api.querybuilder.term.Term; import com.datastax.oss.driver.internal.querybuilder.insert.DefaultInsert; import com.datastax.oss.driver.shaded.guava.common.collect.ImmutableMap; - import java.util.Arrays; import java.util.Map; import org.junit.Test; diff --git a/query-builder/src/test/java/com/datastax/oss/driver/api/querybuilder/select/SelectOrderingTest.java b/query-builder/src/test/java/com/datastax/oss/driver/api/querybuilder/select/SelectOrderingTest.java index 437a705b62e..824f1c48c6b 100644 --- a/query-builder/src/test/java/com/datastax/oss/driver/api/querybuilder/select/SelectOrderingTest.java +++ b/query-builder/src/test/java/com/datastax/oss/driver/api/querybuilder/select/SelectOrderingTest.java @@ -88,11 +88,11 @@ public void should_generate_ann_clause() { } @Test(expected = IllegalArgumentException.class) - public void should_fail_when_provided_ann_with_other_orderings(){ + public void should_fail_when_provided_ann_with_other_orderings() { selectFrom("foo") - .all() - .where(Relation.column("k").isEqualTo(literal(1))) - .orderBy("c1", ASC) - .orderBy(annOf("c1", CqlVector.newInstance(0.1, 0.2, 0.3))); + .all() + .where(Relation.column("k").isEqualTo(literal(1))) + .orderBy("c1", ASC) + .orderBy(annOf("c1", CqlVector.newInstance(0.1, 0.2, 0.3))); } } From 943e3f726183d3af45174618a6e4645d429965de Mon Sep 17 00:00:00 2001 From: janehe Date: Tue, 7 May 2024 13:14:45 -0700 Subject: [PATCH 04/24] DataTypes.custom("org.apache.cassandra.db.marshal.VectorType(org.apache.cassandra.db.marshal.FloatType,3)") --- .../oss/driver/internal/core/type/DefaultVectorType.java | 2 +- .../driver/api/querybuilder/schema/CreateTableTest.java | 9 +++++++++ 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/core/src/main/java/com/datastax/oss/driver/internal/core/type/DefaultVectorType.java b/core/src/main/java/com/datastax/oss/driver/internal/core/type/DefaultVectorType.java index 5915adc2fb3..37647faebb5 100644 --- a/core/src/main/java/com/datastax/oss/driver/internal/core/type/DefaultVectorType.java +++ b/core/src/main/java/com/datastax/oss/driver/internal/core/type/DefaultVectorType.java @@ -60,7 +60,7 @@ public String getClassName() { @NonNull @Override public String asCql(boolean includeFrozen, boolean pretty) { - return String.format("'%s(%d)'", getClassName(), getDimensions()); + return String.format("VECTOR<%s, %d>", this.subtype.asCql(includeFrozen, pretty).toUpperCase(), getDimensions()); } /* ============== General class implementation ============== */ diff --git a/query-builder/src/test/java/com/datastax/oss/driver/api/querybuilder/schema/CreateTableTest.java b/query-builder/src/test/java/com/datastax/oss/driver/api/querybuilder/schema/CreateTableTest.java index d32c66f629b..0ebbf7ec3b4 100644 --- a/query-builder/src/test/java/com/datastax/oss/driver/api/querybuilder/schema/CreateTableTest.java +++ b/query-builder/src/test/java/com/datastax/oss/driver/api/querybuilder/schema/CreateTableTest.java @@ -307,4 +307,13 @@ public void should_generate_create_table_time_window_compaction() { .hasCql( "CREATE TABLE bar (k int PRIMARY KEY,v text) WITH compaction={'class':'TimeWindowCompactionStrategy','compaction_window_size':10,'compaction_window_unit':'DAYS','timestamp_resolution':'MICROSECONDS','unsafe_aggressive_sstable_expiration':false}"); } + + @Test + public void should_generate_vector_column(){ + assertThat(createTable("foo") + .withPartitionKey("k", DataTypes.INT) + .withColumn("v", DataTypes.custom("org.apache.cassandra.db.marshal.VectorType(org.apache.cassandra.db.marshal.FloatType,3)") + )) + .hasCql("CREATE TABLE foo (k int PRIMARY KEY,v VECTOR)"); + } } From d176f09145adca730bd37bd912d554602b5ac787 Mon Sep 17 00:00:00 2001 From: janehe Date: Tue, 7 May 2024 14:54:07 -0700 Subject: [PATCH 05/24] SchemaBuilder add tests --- .../internal/core/type/DefaultVectorType.java | 4 ++-- .../api/querybuilder/schema/AlterTableTest.java | 11 +++++++++++ .../api/querybuilder/schema/AlterTypeTest.java | 7 +++++++ .../api/querybuilder/schema/CreateTableTest.java | 13 +++++++------ .../api/querybuilder/schema/CreateTypeTest.java | 10 ++++++++++ 5 files changed, 37 insertions(+), 8 deletions(-) diff --git a/core/src/main/java/com/datastax/oss/driver/internal/core/type/DefaultVectorType.java b/core/src/main/java/com/datastax/oss/driver/internal/core/type/DefaultVectorType.java index 37647faebb5..762fc931c63 100644 --- a/core/src/main/java/com/datastax/oss/driver/internal/core/type/DefaultVectorType.java +++ b/core/src/main/java/com/datastax/oss/driver/internal/core/type/DefaultVectorType.java @@ -33,7 +33,6 @@ public class DefaultVectorType implements VectorType { private final int dimensions; public DefaultVectorType(DataType subtype, int dimensions) { - this.dimensions = dimensions; this.subtype = subtype; } @@ -60,7 +59,8 @@ public String getClassName() { @NonNull @Override public String asCql(boolean includeFrozen, boolean pretty) { - return String.format("VECTOR<%s, %d>", this.subtype.asCql(includeFrozen, pretty).toUpperCase(), getDimensions()); + return String.format( + "VECTOR<%s, %d>", this.subtype.asCql(includeFrozen, pretty).toUpperCase(), getDimensions()); } /* ============== General class implementation ============== */ diff --git a/query-builder/src/test/java/com/datastax/oss/driver/api/querybuilder/schema/AlterTableTest.java b/query-builder/src/test/java/com/datastax/oss/driver/api/querybuilder/schema/AlterTableTest.java index 1567b0848cf..499e2e08572 100644 --- a/query-builder/src/test/java/com/datastax/oss/driver/api/querybuilder/schema/AlterTableTest.java +++ b/query-builder/src/test/java/com/datastax/oss/driver/api/querybuilder/schema/AlterTableTest.java @@ -108,4 +108,15 @@ public void should_generate_alter_table_with_no_compression() { assertThat(alterTable("bar").withNoCompression()) .hasCql("ALTER TABLE bar WITH compression={'sstable_compression':''}"); } + + @Test + public void should_generate_alter_table_with_vector() { + assertThat( + alterTable("bar") + .alterColumn( + "v", + DataTypes.custom( + "org.apache.cassandra.db.marshal.VectorType(org.apache.cassandra.db.marshal.FloatType,3)"))) + .hasCql("ALTER TABLE bar ALTER v TYPE VECTOR"); + } } diff --git a/query-builder/src/test/java/com/datastax/oss/driver/api/querybuilder/schema/AlterTypeTest.java b/query-builder/src/test/java/com/datastax/oss/driver/api/querybuilder/schema/AlterTypeTest.java index 2becb9338f9..570dc9e6d6f 100644 --- a/query-builder/src/test/java/com/datastax/oss/driver/api/querybuilder/schema/AlterTypeTest.java +++ b/query-builder/src/test/java/com/datastax/oss/driver/api/querybuilder/schema/AlterTypeTest.java @@ -21,6 +21,7 @@ import static com.datastax.oss.driver.api.querybuilder.SchemaBuilder.alterType; import com.datastax.oss.driver.api.core.type.DataTypes; +import com.datastax.oss.driver.internal.core.type.DefaultVectorType; import org.junit.Test; public class AlterTypeTest { @@ -53,4 +54,10 @@ public void should_generate_alter_table_with_rename_three_columns() { assertThat(alterType("bar").renameField("x", "y").renameField("u", "v").renameField("b", "a")) .hasCql("ALTER TYPE bar RENAME x TO y AND u TO v AND b TO a"); } + + @Test + public void should_generate_alter_type_with_vector() { + assertThat(alterType("foo", "bar").alterField("vec", new DefaultVectorType(DataTypes.FLOAT, 3))) + .hasCql("ALTER TYPE foo.bar ALTER vec TYPE VECTOR"); + } } diff --git a/query-builder/src/test/java/com/datastax/oss/driver/api/querybuilder/schema/CreateTableTest.java b/query-builder/src/test/java/com/datastax/oss/driver/api/querybuilder/schema/CreateTableTest.java index 0ebbf7ec3b4..6d8fd538e01 100644 --- a/query-builder/src/test/java/com/datastax/oss/driver/api/querybuilder/schema/CreateTableTest.java +++ b/query-builder/src/test/java/com/datastax/oss/driver/api/querybuilder/schema/CreateTableTest.java @@ -27,6 +27,7 @@ import com.datastax.oss.driver.api.querybuilder.SchemaBuilder.RowsPerPartition; import com.datastax.oss.driver.api.querybuilder.schema.compaction.TimeWindowCompactionStrategy.CompactionWindowUnit; import com.datastax.oss.driver.api.querybuilder.schema.compaction.TimeWindowCompactionStrategy.TimestampResolution; +import com.datastax.oss.driver.internal.core.type.DefaultVectorType; import com.datastax.oss.driver.shaded.guava.common.collect.ImmutableMap; import org.junit.Test; @@ -309,11 +310,11 @@ public void should_generate_create_table_time_window_compaction() { } @Test - public void should_generate_vector_column(){ - assertThat(createTable("foo") - .withPartitionKey("k", DataTypes.INT) - .withColumn("v", DataTypes.custom("org.apache.cassandra.db.marshal.VectorType(org.apache.cassandra.db.marshal.FloatType,3)") - )) - .hasCql("CREATE TABLE foo (k int PRIMARY KEY,v VECTOR)"); + public void should_generate_vector_column() { + assertThat( + createTable("foo") + .withPartitionKey("k", DataTypes.INT) + .withColumn("v", new DefaultVectorType(DataTypes.FLOAT, 3))) + .hasCql("CREATE TABLE foo (k int PRIMARY KEY,v VECTOR)"); } } diff --git a/query-builder/src/test/java/com/datastax/oss/driver/api/querybuilder/schema/CreateTypeTest.java b/query-builder/src/test/java/com/datastax/oss/driver/api/querybuilder/schema/CreateTypeTest.java index d881a0500cb..3c9897ef17f 100644 --- a/query-builder/src/test/java/com/datastax/oss/driver/api/querybuilder/schema/CreateTypeTest.java +++ b/query-builder/src/test/java/com/datastax/oss/driver/api/querybuilder/schema/CreateTypeTest.java @@ -22,6 +22,7 @@ import static com.datastax.oss.driver.api.querybuilder.SchemaBuilder.udt; import com.datastax.oss.driver.api.core.type.DataTypes; +import com.datastax.oss.driver.internal.core.type.DefaultVectorType; import org.junit.Test; public class CreateTypeTest { @@ -83,4 +84,13 @@ public void should_create_type_with_collections() { .withField("map", DataTypes.mapOf(DataTypes.INT, DataTypes.TEXT))) .hasCql("CREATE TYPE ks1.type (map map)"); } + + @Test + public void should_create_type_with_vector() { + assertThat( + createType("ks1", "type") + .withField("c1", DataTypes.INT) + .withField("vec", new DefaultVectorType(DataTypes.FLOAT, 3))) + .hasCql("CREATE TYPE ks1.type (c1 int,vec VECTOR)"); + } } From 953fa47c5380eb91621dfa3c50cd09e7a5ef66a4 Mon Sep 17 00:00:00 2001 From: janehe Date: Tue, 7 May 2024 14:57:37 -0700 Subject: [PATCH 06/24] Add blank line --- .../oss/driver/internal/core/type/DefaultVectorType.java | 1 + 1 file changed, 1 insertion(+) diff --git a/core/src/main/java/com/datastax/oss/driver/internal/core/type/DefaultVectorType.java b/core/src/main/java/com/datastax/oss/driver/internal/core/type/DefaultVectorType.java index 762fc931c63..158ee888652 100644 --- a/core/src/main/java/com/datastax/oss/driver/internal/core/type/DefaultVectorType.java +++ b/core/src/main/java/com/datastax/oss/driver/internal/core/type/DefaultVectorType.java @@ -33,6 +33,7 @@ public class DefaultVectorType implements VectorType { private final int dimensions; public DefaultVectorType(DataType subtype, int dimensions) { + this.dimensions = dimensions; this.subtype = subtype; } From 52db4d544898fa2e655379ccdcce018b85fe16d5 Mon Sep 17 00:00:00 2001 From: janehe Date: Fri, 2 Aug 2024 11:43:49 -0700 Subject: [PATCH 07/24] customize ccm bridge --- .../java/com/datastax/oss/driver/core/data/DataTypeIT.java | 7 +++++++ .../datastax/oss/driver/api/testinfra/ccm/CcmBridge.java | 4 +++- 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/integration-tests/src/test/java/com/datastax/oss/driver/core/data/DataTypeIT.java b/integration-tests/src/test/java/com/datastax/oss/driver/core/data/DataTypeIT.java index a33c8704876..5112e965934 100644 --- a/integration-tests/src/test/java/com/datastax/oss/driver/core/data/DataTypeIT.java +++ b/integration-tests/src/test/java/com/datastax/oss/driver/core/data/DataTypeIT.java @@ -32,6 +32,7 @@ import com.datastax.oss.driver.api.core.cql.SimpleStatement; import com.datastax.oss.driver.api.core.cql.Statement; import com.datastax.oss.driver.api.core.data.CqlDuration; +import com.datastax.oss.driver.api.core.data.CqlVector; import com.datastax.oss.driver.api.core.data.SettableByIndex; import com.datastax.oss.driver.api.core.data.SettableByName; import com.datastax.oss.driver.api.core.data.TupleValue; @@ -53,6 +54,7 @@ import com.datastax.oss.driver.internal.core.type.DefaultSetType; import com.datastax.oss.driver.internal.core.type.DefaultTupleType; import com.datastax.oss.driver.internal.core.type.DefaultUserDefinedType; +import com.datastax.oss.driver.internal.core.type.DefaultVectorType; import com.datastax.oss.protocol.internal.ProtocolConstants; import com.datastax.oss.protocol.internal.util.Bytes; import com.tngtech.java.junit.dataprovider.DataProvider; @@ -263,6 +265,11 @@ public static Object[][] typeSamples() { UdtValue udtValue2 = udt.newValue(1, o[1]); samples.add(new Object[] {udt, udtValue2}); + if (o[0] == DataTypes.INT) { + CqlVector vector = CqlVector.newInstance(1.1f, 2.2f, 3.3f); + samples.add(new Object[]{DataTypes.vectorOf(DataTypes.FLOAT, 3), + vector}); + } return samples.stream(); }) .toArray(Object[][]::new); diff --git a/test-infra/src/main/java/com/datastax/oss/driver/api/testinfra/ccm/CcmBridge.java b/test-infra/src/main/java/com/datastax/oss/driver/api/testinfra/ccm/CcmBridge.java index 98739e7715d..a2630dc5aeb 100644 --- a/test-infra/src/main/java/com/datastax/oss/driver/api/testinfra/ccm/CcmBridge.java +++ b/test-infra/src/main/java/com/datastax/oss/driver/api/testinfra/ccm/CcmBridge.java @@ -408,7 +408,9 @@ protected void processLine(String line, int logLevel) { executor.setStreamHandler(streamHandler); executor.setWatchdog(watchDog); - int retValue = executor.execute(cli); + Map env = new LinkedHashMap<>(System.getenv()); + env.put("JAVA_HOME", "/opt/homebrew/Cellar/openjdk@11/11.0.21/libexec/openjdk.jdk/Contents/Home"); + int retValue = executor.execute(cli, env); if (retValue != 0) { LOG.error("Non-zero exit code ({}) returned from executing ccm command: {}", retValue, cli); } From 1a3c3142fd7c1e953d1326fccb0f7ffa05182fb9 Mon Sep 17 00:00:00 2001 From: janehe Date: Mon, 12 Aug 2024 16:59:01 -0700 Subject: [PATCH 08/24] works for DataTypes.vectorOf(DataTypes.FLOAT, 3) --- .../oss/driver/internal/core/type/DefaultVectorType.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/src/main/java/com/datastax/oss/driver/internal/core/type/DefaultVectorType.java b/core/src/main/java/com/datastax/oss/driver/internal/core/type/DefaultVectorType.java index 158ee888652..63cdae906be 100644 --- a/core/src/main/java/com/datastax/oss/driver/internal/core/type/DefaultVectorType.java +++ b/core/src/main/java/com/datastax/oss/driver/internal/core/type/DefaultVectorType.java @@ -79,7 +79,7 @@ public boolean equals(Object o) { @Override public int hashCode() { - return Objects.hash(super.hashCode(), subtype, dimensions); + return Objects.hash(DefaultVectorType.class, subtype, dimensions); } @Override From 3bbd51947565f36ad2732721b2e5b7af4ef10c38 Mon Sep 17 00:00:00 2001 From: janehe Date: Wed, 14 Aug 2024 00:14:59 -0700 Subject: [PATCH 09/24] Refactor CqlVector to generic type --- .../datastax/oss/driver/api/core/data/CqlVector.java | 11 +++++------ .../oss/driver/api/core/data/GettableById.java | 2 +- .../oss/driver/api/core/data/GettableByIndex.java | 3 +-- .../oss/driver/api/core/data/GettableByName.java | 2 +- .../oss/driver/api/core/data/SettableById.java | 2 +- .../oss/driver/api/core/data/SettableByIndex.java | 2 +- .../oss/driver/api/core/data/SettableByName.java | 2 +- .../oss/driver/api/core/type/codec/TypeCodecs.java | 4 ++-- .../driver/api/core/type/reflect/GenericType.java | 6 ++---- .../driver/internal/core/type/codec/VectorCodec.java | 2 +- .../type/codec/registry/CachingCodecRegistry.java | 12 +++++------- .../internal/core/type/codec/VectorCodecTest.java | 1 + .../datastax/oss/driver/core/data/DataTypeIT.java | 5 ++--- 13 files changed, 24 insertions(+), 30 deletions(-) diff --git a/core/src/main/java/com/datastax/oss/driver/api/core/data/CqlVector.java b/core/src/main/java/com/datastax/oss/driver/api/core/data/CqlVector.java index 911b6187f6d..f98da5cc504 100644 --- a/core/src/main/java/com/datastax/oss/driver/api/core/data/CqlVector.java +++ b/core/src/main/java/com/datastax/oss/driver/api/core/data/CqlVector.java @@ -52,7 +52,7 @@ * where possible we've tried to make the API of this class similar to the equivalent methods on * {@link List}. */ -public class CqlVector implements Iterable, Serializable { +public class CqlVector implements Iterable, Serializable { /** * Create a new CqlVector containing the specified values. @@ -60,7 +60,7 @@ public class CqlVector implements Iterable, Serializable { * @param vals the collection of values to wrap. * @return a CqlVector wrapping those values */ - public static CqlVector newInstance(V... vals) { + public static CqlVector newInstance(V... vals) { // Note that Array.asList() guarantees the return of an array which implements RandomAccess return new CqlVector(Arrays.asList(vals)); @@ -73,7 +73,7 @@ public static CqlVector newInstance(V... vals) { * @param list the collection of values to wrap. * @return a CqlVector wrapping those values */ - public static CqlVector newInstance(List list) { + public static CqlVector newInstance(List list) { Preconditions.checkArgument(list != null, "Input list should not be null"); return new CqlVector(list); } @@ -87,8 +87,7 @@ public static CqlVector newInstance(List list) { * @param subtypeCodec * @return a new CqlVector built from the String representation */ - public static CqlVector from( - @NonNull String str, @NonNull TypeCodec subtypeCodec) { + public static CqlVector from(@NonNull String str, @NonNull TypeCodec subtypeCodec) { Preconditions.checkArgument(str != null, "Cannot create CqlVector from null string"); Preconditions.checkArgument(!str.isEmpty(), "Cannot create CqlVector from empty string"); ArrayList vals = @@ -205,7 +204,7 @@ public String toString() { * * @param inner type of CqlVector, assume Number is always Serializable. */ - private static class SerializationProxy implements Serializable { + private static class SerializationProxy implements Serializable { private static final long serialVersionUID = 1; diff --git a/core/src/main/java/com/datastax/oss/driver/api/core/data/GettableById.java b/core/src/main/java/com/datastax/oss/driver/api/core/data/GettableById.java index 0a24214b20a..8393bc9f758 100644 --- a/core/src/main/java/com/datastax/oss/driver/api/core/data/GettableById.java +++ b/core/src/main/java/com/datastax/oss/driver/api/core/data/GettableById.java @@ -531,7 +531,7 @@ default CqlDuration getCqlDuration(@NonNull CqlIdentifier id) { * @throws IllegalArgumentException if the id is invalid. */ @Nullable - default CqlVector getVector( + default CqlVector getVector( @NonNull CqlIdentifier id, @NonNull Class elementsClass) { return getVector(firstIndexOf(id), elementsClass); } diff --git a/core/src/main/java/com/datastax/oss/driver/api/core/data/GettableByIndex.java b/core/src/main/java/com/datastax/oss/driver/api/core/data/GettableByIndex.java index 53541b0ac58..bb75bd9a2b4 100644 --- a/core/src/main/java/com/datastax/oss/driver/api/core/data/GettableByIndex.java +++ b/core/src/main/java/com/datastax/oss/driver/api/core/data/GettableByIndex.java @@ -446,8 +446,7 @@ default CqlDuration getCqlDuration(int i) { * @throws IndexOutOfBoundsException if the index is invalid. */ @Nullable - default CqlVector getVector( - int i, @NonNull Class elementsClass) { + default CqlVector getVector(int i, @NonNull Class elementsClass) { return get(i, GenericType.vectorOf(elementsClass)); } diff --git a/core/src/main/java/com/datastax/oss/driver/api/core/data/GettableByName.java b/core/src/main/java/com/datastax/oss/driver/api/core/data/GettableByName.java index ec3ee362ca8..b0a4660033b 100644 --- a/core/src/main/java/com/datastax/oss/driver/api/core/data/GettableByName.java +++ b/core/src/main/java/com/datastax/oss/driver/api/core/data/GettableByName.java @@ -527,7 +527,7 @@ default CqlDuration getCqlDuration(@NonNull String name) { * @throws IllegalArgumentException if the name is invalid. */ @Nullable - default CqlVector getVector( + default CqlVector getVector( @NonNull String name, @NonNull Class elementsClass) { return getVector(firstIndexOf(name), elementsClass); } diff --git a/core/src/main/java/com/datastax/oss/driver/api/core/data/SettableById.java b/core/src/main/java/com/datastax/oss/driver/api/core/data/SettableById.java index 8452446205e..0f5e3cd9daa 100644 --- a/core/src/main/java/com/datastax/oss/driver/api/core/data/SettableById.java +++ b/core/src/main/java/com/datastax/oss/driver/api/core/data/SettableById.java @@ -573,7 +573,7 @@ default SelfT setCqlDuration(@NonNull CqlIdentifier id, @Nullable CqlDuration v) */ @NonNull @CheckReturnValue - default SelfT setVector( + default SelfT setVector( @NonNull CqlIdentifier id, @Nullable CqlVector v, @NonNull Class elementsClass) { diff --git a/core/src/main/java/com/datastax/oss/driver/api/core/data/SettableByIndex.java b/core/src/main/java/com/datastax/oss/driver/api/core/data/SettableByIndex.java index bb55db3adde..4ecdf647590 100644 --- a/core/src/main/java/com/datastax/oss/driver/api/core/data/SettableByIndex.java +++ b/core/src/main/java/com/datastax/oss/driver/api/core/data/SettableByIndex.java @@ -425,7 +425,7 @@ default SelfT setCqlDuration(int i, @Nullable CqlDuration v) { */ @NonNull @CheckReturnValue - default SelfT setVector( + default SelfT setVector( int i, @Nullable CqlVector v, @NonNull Class elementsClass) { return set(i, v, GenericType.vectorOf(elementsClass)); } diff --git a/core/src/main/java/com/datastax/oss/driver/api/core/data/SettableByName.java b/core/src/main/java/com/datastax/oss/driver/api/core/data/SettableByName.java index c25a7074373..afe9ba59f64 100644 --- a/core/src/main/java/com/datastax/oss/driver/api/core/data/SettableByName.java +++ b/core/src/main/java/com/datastax/oss/driver/api/core/data/SettableByName.java @@ -572,7 +572,7 @@ default SelfT setCqlDuration(@NonNull String name, @Nullable CqlDuration v) { */ @NonNull @CheckReturnValue - default SelfT setVector( + default SelfT setVector( @NonNull String name, @Nullable CqlVector v, @NonNull Class elementsClass) { diff --git a/core/src/main/java/com/datastax/oss/driver/api/core/type/codec/TypeCodecs.java b/core/src/main/java/com/datastax/oss/driver/api/core/type/codec/TypeCodecs.java index 9f2fd5cc69e..68f1b07b106 100644 --- a/core/src/main/java/com/datastax/oss/driver/api/core/type/codec/TypeCodecs.java +++ b/core/src/main/java/com/datastax/oss/driver/api/core/type/codec/TypeCodecs.java @@ -210,13 +210,13 @@ public static TypeCodec tupleOf(@NonNull TupleType cqlType) { return new TupleCodec(cqlType); } - public static TypeCodec> vectorOf( + public static TypeCodec> vectorOf( @NonNull VectorType type, @NonNull TypeCodec subtypeCodec) { return new VectorCodec( DataTypes.vectorOf(subtypeCodec.getCqlType(), type.getDimensions()), subtypeCodec); } - public static TypeCodec> vectorOf( + public static TypeCodec> vectorOf( int dimensions, @NonNull TypeCodec subtypeCodec) { return new VectorCodec(DataTypes.vectorOf(subtypeCodec.getCqlType(), dimensions), subtypeCodec); } diff --git a/core/src/main/java/com/datastax/oss/driver/api/core/type/reflect/GenericType.java b/core/src/main/java/com/datastax/oss/driver/api/core/type/reflect/GenericType.java index c6482d4f4d1..d22b6f1bfaf 100644 --- a/core/src/main/java/com/datastax/oss/driver/api/core/type/reflect/GenericType.java +++ b/core/src/main/java/com/datastax/oss/driver/api/core/type/reflect/GenericType.java @@ -151,8 +151,7 @@ public static GenericType> setOf(@NonNull GenericType elementType) } @NonNull - public static GenericType> vectorOf( - @NonNull Class elementType) { + public static GenericType> vectorOf(@NonNull Class elementType) { TypeToken> token = new TypeToken>() {}.where( new TypeParameter() {}, TypeToken.of(elementType)); @@ -160,8 +159,7 @@ public static GenericType> vectorOf( } @NonNull - public static GenericType> vectorOf( - @NonNull GenericType elementType) { + public static GenericType> vectorOf(@NonNull GenericType elementType) { TypeToken> token = new TypeToken>() {}.where(new TypeParameter() {}, elementType.token); return new GenericType<>(token); diff --git a/core/src/main/java/com/datastax/oss/driver/internal/core/type/codec/VectorCodec.java b/core/src/main/java/com/datastax/oss/driver/internal/core/type/codec/VectorCodec.java index 2c4d2200b13..bfbff061e26 100644 --- a/core/src/main/java/com/datastax/oss/driver/internal/core/type/codec/VectorCodec.java +++ b/core/src/main/java/com/datastax/oss/driver/internal/core/type/codec/VectorCodec.java @@ -33,7 +33,7 @@ import java.util.List; import java.util.NoSuchElementException; -public class VectorCodec implements TypeCodec> { +public class VectorCodec implements TypeCodec> { private final VectorType cqlType; private final GenericType> javaType; diff --git a/core/src/main/java/com/datastax/oss/driver/internal/core/type/codec/registry/CachingCodecRegistry.java b/core/src/main/java/com/datastax/oss/driver/internal/core/type/codec/registry/CachingCodecRegistry.java index 495d6227d93..3af5a30ba27 100644 --- a/core/src/main/java/com/datastax/oss/driver/internal/core/type/codec/registry/CachingCodecRegistry.java +++ b/core/src/main/java/com/datastax/oss/driver/internal/core/type/codec/registry/CachingCodecRegistry.java @@ -394,10 +394,9 @@ protected GenericType inspectType(@NonNull Object value, @Nullable DataType c "Can't infer vector codec because the first element is null " + "(note that CQL does not allow null values in collections)"); } - GenericType elementType = - (GenericType) - inspectType( - firstElement, cqlType == null ? null : ((VectorType) cqlType).getElementType()); + GenericType elementType = + inspectType( + firstElement, cqlType == null ? null : ((VectorType) cqlType).getElementType()); return GenericType.vectorOf(elementType); } } else { @@ -421,8 +420,7 @@ protected GenericType inferJavaTypeFromCqlType(@NonNull DataType cqlType) { inferJavaTypeFromCqlType(keyType), inferJavaTypeFromCqlType(valueType)); } else if (cqlType instanceof VectorType) { DataType elementType = ((VectorType) cqlType).getElementType(); - GenericType numberType = - (GenericType) inferJavaTypeFromCqlType(elementType); + GenericType numberType = inferJavaTypeFromCqlType(elementType); return GenericType.vectorOf(numberType); } switch (cqlType.getProtocolCode()) { @@ -657,7 +655,7 @@ protected TypeCodec createCodec( /* For a vector type we'll always get back an instance of TypeCodec due to the * type of CqlVector... but getElementCodecForCqlAndJavaType() is a generalized function that can't * return this more precise type. Thus the cast here. */ - TypeCodec elementCodec = + TypeCodec elementCodec = uncheckedCast(getElementCodecForCqlAndJavaType(vectorType, token, isJavaCovariant)); return TypeCodecs.vectorOf(vectorType, elementCodec); } else if (cqlType instanceof CustomType diff --git a/core/src/test/java/com/datastax/oss/driver/internal/core/type/codec/VectorCodecTest.java b/core/src/test/java/com/datastax/oss/driver/internal/core/type/codec/VectorCodecTest.java index 969d35cbbbe..ee086ea2a84 100644 --- a/core/src/test/java/com/datastax/oss/driver/internal/core/type/codec/VectorCodecTest.java +++ b/core/src/test/java/com/datastax/oss/driver/internal/core/type/codec/VectorCodecTest.java @@ -29,6 +29,7 @@ import java.util.Arrays; import org.junit.Test; +/** Only for Float TODO: add others */ public class VectorCodecTest extends CodecTestBase> { private static final Float[] VECTOR_ARGS = {1.0f, 2.5f}; diff --git a/integration-tests/src/test/java/com/datastax/oss/driver/core/data/DataTypeIT.java b/integration-tests/src/test/java/com/datastax/oss/driver/core/data/DataTypeIT.java index 5112e965934..3a1a9816fb6 100644 --- a/integration-tests/src/test/java/com/datastax/oss/driver/core/data/DataTypeIT.java +++ b/integration-tests/src/test/java/com/datastax/oss/driver/core/data/DataTypeIT.java @@ -54,7 +54,6 @@ import com.datastax.oss.driver.internal.core.type.DefaultSetType; import com.datastax.oss.driver.internal.core.type.DefaultTupleType; import com.datastax.oss.driver.internal.core.type.DefaultUserDefinedType; -import com.datastax.oss.driver.internal.core.type.DefaultVectorType; import com.datastax.oss.protocol.internal.ProtocolConstants; import com.datastax.oss.protocol.internal.util.Bytes; import com.tngtech.java.junit.dataprovider.DataProvider; @@ -265,10 +264,10 @@ public static Object[][] typeSamples() { UdtValue udtValue2 = udt.newValue(1, o[1]); samples.add(new Object[] {udt, udtValue2}); + // change the vector subtype into arbitrary type if (o[0] == DataTypes.INT) { CqlVector vector = CqlVector.newInstance(1.1f, 2.2f, 3.3f); - samples.add(new Object[]{DataTypes.vectorOf(DataTypes.FLOAT, 3), - vector}); + samples.add(new Object[] {DataTypes.vectorOf(DataTypes.FLOAT, 3), vector}); } return samples.stream(); }) From 1645b7806dfece5b3c089d2149db60bcef7bbee1 Mon Sep 17 00:00:00 2001 From: janehe Date: Tue, 20 Aug 2024 17:14:52 -0800 Subject: [PATCH 10/24] serialize size and migrated fixed&var length codecs, not tested --- .../driver/api/core/type/codec/TypeCodec.java | 6 + .../internal/core/type/codec/BigIntCodec.java | 7 + .../internal/core/type/codec/BlobCodec.java | 7 + .../core/type/codec/BooleanCodec.java | 7 + .../core/type/codec/CounterCodec.java | 7 + .../core/type/codec/CqlDurationCodec.java | 7 + .../internal/core/type/codec/DateCodec.java | 7 + .../core/type/codec/DecimalCodec.java | 7 + .../internal/core/type/codec/DoubleCodec.java | 7 + .../internal/core/type/codec/FloatCodec.java | 7 + .../internal/core/type/codec/InetCodec.java | 7 + .../internal/core/type/codec/IntCodec.java | 7 + .../core/type/codec/SmallIntCodec.java | 7 + .../internal/core/type/codec/StringCodec.java | 7 + .../internal/core/type/codec/TimeCodec.java | 7 + .../core/type/codec/TimestampCodec.java | 7 + .../core/type/codec/TinyIntCodec.java | 7 + .../internal/core/type/codec/UuidCodec.java | 7 + .../internal/core/type/codec/VectorCodec.java | 246 ++++++++++++------ .../extras/time/TimestampMillisCodec.java | 7 + .../internal/core/type/util/VIntCoding.java | 77 +++++- 21 files changed, 381 insertions(+), 74 deletions(-) diff --git a/core/src/main/java/com/datastax/oss/driver/api/core/type/codec/TypeCodec.java b/core/src/main/java/com/datastax/oss/driver/api/core/type/codec/TypeCodec.java index 05ae3980823..cdaa6864292 100644 --- a/core/src/main/java/com/datastax/oss/driver/api/core/type/codec/TypeCodec.java +++ b/core/src/main/java/com/datastax/oss/driver/api/core/type/codec/TypeCodec.java @@ -24,6 +24,7 @@ import com.datastax.oss.driver.api.core.metadata.schema.AggregateMetadata; import com.datastax.oss.driver.api.core.type.DataType; import com.datastax.oss.driver.api.core.type.reflect.GenericType; +import com.datastax.oss.driver.shaded.guava.common.base.Optional; import com.datastax.oss.driver.shaded.guava.common.base.Preconditions; import edu.umd.cs.findbugs.annotations.NonNull; import edu.umd.cs.findbugs.annotations.Nullable; @@ -234,4 +235,9 @@ default boolean accepts(@NonNull DataType cqlType) { */ @Nullable JavaTypeT parse(@Nullable String value); + + @NonNull + default Optional serializedSize() { + return Optional.absent(); + } } diff --git a/core/src/main/java/com/datastax/oss/driver/internal/core/type/codec/BigIntCodec.java b/core/src/main/java/com/datastax/oss/driver/internal/core/type/codec/BigIntCodec.java index 2b3b8255cc1..18a5a7c15cd 100644 --- a/core/src/main/java/com/datastax/oss/driver/internal/core/type/codec/BigIntCodec.java +++ b/core/src/main/java/com/datastax/oss/driver/internal/core/type/codec/BigIntCodec.java @@ -22,6 +22,7 @@ import com.datastax.oss.driver.api.core.type.DataTypes; import com.datastax.oss.driver.api.core.type.codec.PrimitiveLongCodec; import com.datastax.oss.driver.api.core.type.reflect.GenericType; +import com.datastax.oss.driver.shaded.guava.common.base.Optional; import edu.umd.cs.findbugs.annotations.NonNull; import edu.umd.cs.findbugs.annotations.Nullable; import java.nio.ByteBuffer; @@ -90,4 +91,10 @@ public Long parse(@Nullable String value) { String.format("Cannot parse 64-bits long value from \"%s\"", value)); } } + + @NonNull + @Override + public Optional serializedSize() { + return Optional.of(8); + } } diff --git a/core/src/main/java/com/datastax/oss/driver/internal/core/type/codec/BlobCodec.java b/core/src/main/java/com/datastax/oss/driver/internal/core/type/codec/BlobCodec.java index 1f5fcd5eeaa..258c0240b7a 100644 --- a/core/src/main/java/com/datastax/oss/driver/internal/core/type/codec/BlobCodec.java +++ b/core/src/main/java/com/datastax/oss/driver/internal/core/type/codec/BlobCodec.java @@ -22,6 +22,7 @@ import com.datastax.oss.driver.api.core.type.DataTypes; import com.datastax.oss.driver.api.core.type.codec.TypeCodec; import com.datastax.oss.driver.api.core.type.reflect.GenericType; +import com.datastax.oss.driver.shaded.guava.common.base.Optional; import com.datastax.oss.protocol.internal.util.Bytes; import edu.umd.cs.findbugs.annotations.NonNull; import edu.umd.cs.findbugs.annotations.Nullable; @@ -83,4 +84,10 @@ public ByteBuffer parse(@Nullable String value) { ? null : Bytes.fromHexString(value); } + + @NonNull + @Override + public Optional serializedSize() { + return Optional.absent(); + } } diff --git a/core/src/main/java/com/datastax/oss/driver/internal/core/type/codec/BooleanCodec.java b/core/src/main/java/com/datastax/oss/driver/internal/core/type/codec/BooleanCodec.java index 7a982a9e6ca..c99a8f28846 100644 --- a/core/src/main/java/com/datastax/oss/driver/internal/core/type/codec/BooleanCodec.java +++ b/core/src/main/java/com/datastax/oss/driver/internal/core/type/codec/BooleanCodec.java @@ -22,6 +22,7 @@ import com.datastax.oss.driver.api.core.type.DataTypes; import com.datastax.oss.driver.api.core.type.codec.PrimitiveBooleanCodec; import com.datastax.oss.driver.api.core.type.reflect.GenericType; +import com.datastax.oss.driver.shaded.guava.common.base.Optional; import edu.umd.cs.findbugs.annotations.NonNull; import edu.umd.cs.findbugs.annotations.Nullable; import java.nio.ByteBuffer; @@ -98,4 +99,10 @@ public Boolean parse(@Nullable String value) { String.format("Cannot parse boolean value from \"%s\"", value)); } } + + @NonNull + @Override + public Optional serializedSize() { + return Optional.of(1); + } } diff --git a/core/src/main/java/com/datastax/oss/driver/internal/core/type/codec/CounterCodec.java b/core/src/main/java/com/datastax/oss/driver/internal/core/type/codec/CounterCodec.java index ab90ba09c20..5826d0d5512 100644 --- a/core/src/main/java/com/datastax/oss/driver/internal/core/type/codec/CounterCodec.java +++ b/core/src/main/java/com/datastax/oss/driver/internal/core/type/codec/CounterCodec.java @@ -19,6 +19,7 @@ import com.datastax.oss.driver.api.core.type.DataType; import com.datastax.oss.driver.api.core.type.DataTypes; +import com.datastax.oss.driver.shaded.guava.common.base.Optional; import edu.umd.cs.findbugs.annotations.NonNull; import net.jcip.annotations.ThreadSafe; @@ -29,4 +30,10 @@ public class CounterCodec extends BigIntCodec { public DataType getCqlType() { return DataTypes.COUNTER; } + + @NonNull + @Override + public Optional serializedSize() { + return Optional.absent(); + } } diff --git a/core/src/main/java/com/datastax/oss/driver/internal/core/type/codec/CqlDurationCodec.java b/core/src/main/java/com/datastax/oss/driver/internal/core/type/codec/CqlDurationCodec.java index 90f6f56cf06..bc34218d802 100644 --- a/core/src/main/java/com/datastax/oss/driver/internal/core/type/codec/CqlDurationCodec.java +++ b/core/src/main/java/com/datastax/oss/driver/internal/core/type/codec/CqlDurationCodec.java @@ -24,6 +24,7 @@ import com.datastax.oss.driver.api.core.type.codec.TypeCodec; import com.datastax.oss.driver.api.core.type.reflect.GenericType; import com.datastax.oss.driver.internal.core.type.util.VIntCoding; +import com.datastax.oss.driver.shaded.guava.common.base.Optional; import com.datastax.oss.driver.shaded.guava.common.io.ByteArrayDataOutput; import com.datastax.oss.driver.shaded.guava.common.io.ByteStreams; import com.datastax.oss.protocol.internal.util.Bytes; @@ -115,4 +116,10 @@ public CqlDuration parse(@Nullable String value) { ? null : CqlDuration.from(value); } + + @NonNull + @Override + public Optional serializedSize() { + return Optional.absent(); + } } diff --git a/core/src/main/java/com/datastax/oss/driver/internal/core/type/codec/DateCodec.java b/core/src/main/java/com/datastax/oss/driver/internal/core/type/codec/DateCodec.java index 2fc463ef7d2..da499687ef8 100644 --- a/core/src/main/java/com/datastax/oss/driver/internal/core/type/codec/DateCodec.java +++ b/core/src/main/java/com/datastax/oss/driver/internal/core/type/codec/DateCodec.java @@ -26,6 +26,7 @@ import com.datastax.oss.driver.api.core.type.codec.TypeCodecs; import com.datastax.oss.driver.api.core.type.reflect.GenericType; import com.datastax.oss.driver.internal.core.util.Strings; +import com.datastax.oss.driver.shaded.guava.common.base.Optional; import edu.umd.cs.findbugs.annotations.NonNull; import edu.umd.cs.findbugs.annotations.Nullable; import java.nio.ByteBuffer; @@ -152,4 +153,10 @@ private static int cqlDateToDaysSinceEpoch(long raw) { private static final long MAX_CQL_LONG_VALUE = ((1L << 32) - 1); private static final long EPOCH_AS_CQL_LONG = (1L << 31); + + @NonNull + @Override + public Optional serializedSize() { + return Optional.of(8); + } } diff --git a/core/src/main/java/com/datastax/oss/driver/internal/core/type/codec/DecimalCodec.java b/core/src/main/java/com/datastax/oss/driver/internal/core/type/codec/DecimalCodec.java index 25650b733cd..562828fb1bc 100644 --- a/core/src/main/java/com/datastax/oss/driver/internal/core/type/codec/DecimalCodec.java +++ b/core/src/main/java/com/datastax/oss/driver/internal/core/type/codec/DecimalCodec.java @@ -22,6 +22,7 @@ import com.datastax.oss.driver.api.core.type.DataTypes; import com.datastax.oss.driver.api.core.type.codec.TypeCodec; import com.datastax.oss.driver.api.core.type.reflect.GenericType; +import com.datastax.oss.driver.shaded.guava.common.base.Optional; import edu.umd.cs.findbugs.annotations.NonNull; import edu.umd.cs.findbugs.annotations.Nullable; import java.math.BigDecimal; @@ -107,4 +108,10 @@ public BigDecimal parse(@Nullable String value) { String.format("Cannot parse decimal value from \"%s\"", value)); } } + + @NonNull + @Override + public Optional serializedSize() { + return Optional.absent(); + } } diff --git a/core/src/main/java/com/datastax/oss/driver/internal/core/type/codec/DoubleCodec.java b/core/src/main/java/com/datastax/oss/driver/internal/core/type/codec/DoubleCodec.java index 28eff6f9463..5619a4069b4 100644 --- a/core/src/main/java/com/datastax/oss/driver/internal/core/type/codec/DoubleCodec.java +++ b/core/src/main/java/com/datastax/oss/driver/internal/core/type/codec/DoubleCodec.java @@ -22,6 +22,7 @@ import com.datastax.oss.driver.api.core.type.DataTypes; import com.datastax.oss.driver.api.core.type.codec.PrimitiveDoubleCodec; import com.datastax.oss.driver.api.core.type.reflect.GenericType; +import com.datastax.oss.driver.shaded.guava.common.base.Optional; import edu.umd.cs.findbugs.annotations.NonNull; import edu.umd.cs.findbugs.annotations.Nullable; import java.nio.ByteBuffer; @@ -90,4 +91,10 @@ public Double parse(@Nullable String value) { String.format("Cannot parse 64-bits double value from \"%s\"", value)); } } + + @NonNull + @Override + public Optional serializedSize() { + return Optional.of(8); + } } diff --git a/core/src/main/java/com/datastax/oss/driver/internal/core/type/codec/FloatCodec.java b/core/src/main/java/com/datastax/oss/driver/internal/core/type/codec/FloatCodec.java index 11786dbc77d..5c92cb780ef 100644 --- a/core/src/main/java/com/datastax/oss/driver/internal/core/type/codec/FloatCodec.java +++ b/core/src/main/java/com/datastax/oss/driver/internal/core/type/codec/FloatCodec.java @@ -22,6 +22,7 @@ import com.datastax.oss.driver.api.core.type.DataTypes; import com.datastax.oss.driver.api.core.type.codec.PrimitiveFloatCodec; import com.datastax.oss.driver.api.core.type.reflect.GenericType; +import com.datastax.oss.driver.shaded.guava.common.base.Optional; import edu.umd.cs.findbugs.annotations.NonNull; import edu.umd.cs.findbugs.annotations.Nullable; import java.nio.ByteBuffer; @@ -90,4 +91,10 @@ public Float parse(@Nullable String value) { String.format("Cannot parse 32-bits float value from \"%s\"", value)); } } + + @NonNull + @Override + public Optional serializedSize() { + return Optional.of(4); + } } diff --git a/core/src/main/java/com/datastax/oss/driver/internal/core/type/codec/InetCodec.java b/core/src/main/java/com/datastax/oss/driver/internal/core/type/codec/InetCodec.java index 167c7109bf9..726038d1c7b 100644 --- a/core/src/main/java/com/datastax/oss/driver/internal/core/type/codec/InetCodec.java +++ b/core/src/main/java/com/datastax/oss/driver/internal/core/type/codec/InetCodec.java @@ -23,6 +23,7 @@ import com.datastax.oss.driver.api.core.type.codec.TypeCodec; import com.datastax.oss.driver.api.core.type.reflect.GenericType; import com.datastax.oss.driver.internal.core.util.Strings; +import com.datastax.oss.driver.shaded.guava.common.base.Optional; import com.datastax.oss.protocol.internal.util.Bytes; import edu.umd.cs.findbugs.annotations.NonNull; import edu.umd.cs.findbugs.annotations.Nullable; @@ -100,4 +101,10 @@ public InetAddress parse(@Nullable String value) { String.format("Cannot parse inet value from \"%s\"", value)); } } + + @NonNull + @Override + public Optional serializedSize() { + return Optional.absent(); + } } diff --git a/core/src/main/java/com/datastax/oss/driver/internal/core/type/codec/IntCodec.java b/core/src/main/java/com/datastax/oss/driver/internal/core/type/codec/IntCodec.java index e5bb530ba79..98629baecd0 100644 --- a/core/src/main/java/com/datastax/oss/driver/internal/core/type/codec/IntCodec.java +++ b/core/src/main/java/com/datastax/oss/driver/internal/core/type/codec/IntCodec.java @@ -22,6 +22,7 @@ import com.datastax.oss.driver.api.core.type.DataTypes; import com.datastax.oss.driver.api.core.type.codec.PrimitiveIntCodec; import com.datastax.oss.driver.api.core.type.reflect.GenericType; +import com.datastax.oss.driver.shaded.guava.common.base.Optional; import edu.umd.cs.findbugs.annotations.NonNull; import edu.umd.cs.findbugs.annotations.Nullable; import java.nio.ByteBuffer; @@ -90,4 +91,10 @@ public Integer parse(@Nullable String value) { String.format("Cannot parse 32-bits int value from \"%s\"", value)); } } + + @NonNull + @Override + public Optional serializedSize() { + return Optional.of(4); + } } diff --git a/core/src/main/java/com/datastax/oss/driver/internal/core/type/codec/SmallIntCodec.java b/core/src/main/java/com/datastax/oss/driver/internal/core/type/codec/SmallIntCodec.java index 08beb0b34c5..0b91c1f429b 100644 --- a/core/src/main/java/com/datastax/oss/driver/internal/core/type/codec/SmallIntCodec.java +++ b/core/src/main/java/com/datastax/oss/driver/internal/core/type/codec/SmallIntCodec.java @@ -22,6 +22,7 @@ import com.datastax.oss.driver.api.core.type.DataTypes; import com.datastax.oss.driver.api.core.type.codec.PrimitiveShortCodec; import com.datastax.oss.driver.api.core.type.reflect.GenericType; +import com.datastax.oss.driver.shaded.guava.common.base.Optional; import edu.umd.cs.findbugs.annotations.NonNull; import edu.umd.cs.findbugs.annotations.Nullable; import java.nio.ByteBuffer; @@ -90,4 +91,10 @@ public Short parse(@Nullable String value) { String.format("Cannot parse 16-bits int value from \"%s\"", value)); } } + + @NonNull + @Override + public Optional serializedSize() { + return Optional.absent(); + } } diff --git a/core/src/main/java/com/datastax/oss/driver/internal/core/type/codec/StringCodec.java b/core/src/main/java/com/datastax/oss/driver/internal/core/type/codec/StringCodec.java index 2a9acdd8c47..364e5b9f7de 100644 --- a/core/src/main/java/com/datastax/oss/driver/internal/core/type/codec/StringCodec.java +++ b/core/src/main/java/com/datastax/oss/driver/internal/core/type/codec/StringCodec.java @@ -22,6 +22,7 @@ import com.datastax.oss.driver.api.core.type.codec.TypeCodec; import com.datastax.oss.driver.api.core.type.reflect.GenericType; import com.datastax.oss.driver.internal.core.util.Strings; +import com.datastax.oss.driver.shaded.guava.common.base.Optional; import edu.umd.cs.findbugs.annotations.NonNull; import edu.umd.cs.findbugs.annotations.Nullable; import io.netty.util.concurrent.FastThreadLocal; @@ -134,4 +135,10 @@ public String parse(String value) { return Strings.unquote(value); } } + + @NonNull + @Override + public Optional serializedSize() { + return Optional.absent(); + } } diff --git a/core/src/main/java/com/datastax/oss/driver/internal/core/type/codec/TimeCodec.java b/core/src/main/java/com/datastax/oss/driver/internal/core/type/codec/TimeCodec.java index 4977687342d..2295adfae6a 100644 --- a/core/src/main/java/com/datastax/oss/driver/internal/core/type/codec/TimeCodec.java +++ b/core/src/main/java/com/datastax/oss/driver/internal/core/type/codec/TimeCodec.java @@ -24,6 +24,7 @@ import com.datastax.oss.driver.api.core.type.codec.TypeCodecs; import com.datastax.oss.driver.api.core.type.reflect.GenericType; import com.datastax.oss.driver.internal.core.util.Strings; +import com.datastax.oss.driver.shaded.guava.common.base.Optional; import edu.umd.cs.findbugs.annotations.NonNull; import edu.umd.cs.findbugs.annotations.Nullable; import java.nio.ByteBuffer; @@ -113,4 +114,10 @@ public LocalTime parse(@Nullable String value) { String.format("Cannot parse time value from \"%s\"", value), e); } } + + @NonNull + @Override + public Optional serializedSize() { + return Optional.of(8); + } } diff --git a/core/src/main/java/com/datastax/oss/driver/internal/core/type/codec/TimestampCodec.java b/core/src/main/java/com/datastax/oss/driver/internal/core/type/codec/TimestampCodec.java index eeba3c7c66c..a98538ad1c8 100644 --- a/core/src/main/java/com/datastax/oss/driver/internal/core/type/codec/TimestampCodec.java +++ b/core/src/main/java/com/datastax/oss/driver/internal/core/type/codec/TimestampCodec.java @@ -24,6 +24,7 @@ import com.datastax.oss.driver.api.core.type.codec.TypeCodecs; import com.datastax.oss.driver.api.core.type.reflect.GenericType; import com.datastax.oss.driver.internal.core.util.Strings; +import com.datastax.oss.driver.shaded.guava.common.base.Optional; import edu.umd.cs.findbugs.annotations.NonNull; import edu.umd.cs.findbugs.annotations.Nullable; import io.netty.util.concurrent.FastThreadLocal; @@ -293,4 +294,10 @@ public Instant parse(@Nullable String value) { String.format("Cannot parse timestamp value from \"%s\"", value)); } } + + @NonNull + @Override + public Optional serializedSize() { + return Optional.of(8); + } } diff --git a/core/src/main/java/com/datastax/oss/driver/internal/core/type/codec/TinyIntCodec.java b/core/src/main/java/com/datastax/oss/driver/internal/core/type/codec/TinyIntCodec.java index 13bf79b70d5..6c27864fc12 100644 --- a/core/src/main/java/com/datastax/oss/driver/internal/core/type/codec/TinyIntCodec.java +++ b/core/src/main/java/com/datastax/oss/driver/internal/core/type/codec/TinyIntCodec.java @@ -22,6 +22,7 @@ import com.datastax.oss.driver.api.core.type.DataTypes; import com.datastax.oss.driver.api.core.type.codec.PrimitiveByteCodec; import com.datastax.oss.driver.api.core.type.reflect.GenericType; +import com.datastax.oss.driver.shaded.guava.common.base.Optional; import edu.umd.cs.findbugs.annotations.NonNull; import edu.umd.cs.findbugs.annotations.Nullable; import java.nio.ByteBuffer; @@ -90,4 +91,10 @@ public Byte parse(@Nullable String value) { String.format("Cannot parse 8-bits int value from \"%s\"", value)); } } + + @NonNull + @Override + public Optional serializedSize() { + return Optional.absent(); + } } diff --git a/core/src/main/java/com/datastax/oss/driver/internal/core/type/codec/UuidCodec.java b/core/src/main/java/com/datastax/oss/driver/internal/core/type/codec/UuidCodec.java index 57feac4ae7e..06662848f78 100644 --- a/core/src/main/java/com/datastax/oss/driver/internal/core/type/codec/UuidCodec.java +++ b/core/src/main/java/com/datastax/oss/driver/internal/core/type/codec/UuidCodec.java @@ -22,6 +22,7 @@ import com.datastax.oss.driver.api.core.type.DataTypes; import com.datastax.oss.driver.api.core.type.codec.TypeCodec; import com.datastax.oss.driver.api.core.type.reflect.GenericType; +import com.datastax.oss.driver.shaded.guava.common.base.Optional; import edu.umd.cs.findbugs.annotations.NonNull; import edu.umd.cs.findbugs.annotations.Nullable; import java.nio.ByteBuffer; @@ -95,4 +96,10 @@ public UUID parse(@Nullable String value) { String.format("Cannot parse UUID value from \"%s\"", value), e); } } + + @NonNull + @Override + public Optional serializedSize() { + return Optional.of(16); + } } diff --git a/core/src/main/java/com/datastax/oss/driver/internal/core/type/codec/VectorCodec.java b/core/src/main/java/com/datastax/oss/driver/internal/core/type/codec/VectorCodec.java index bfbff061e26..04dbf50c681 100644 --- a/core/src/main/java/com/datastax/oss/driver/internal/core/type/codec/VectorCodec.java +++ b/core/src/main/java/com/datastax/oss/driver/internal/core/type/codec/VectorCodec.java @@ -24,6 +24,7 @@ import com.datastax.oss.driver.api.core.type.codec.TypeCodec; import com.datastax.oss.driver.api.core.type.reflect.GenericType; import com.datastax.oss.driver.internal.core.type.DefaultVectorType; +import com.datastax.oss.driver.internal.core.type.util.VIntCoding; import com.datastax.oss.driver.shaded.guava.common.collect.Iterables; import edu.umd.cs.findbugs.annotations.NonNull; import edu.umd.cs.findbugs.annotations.Nullable; @@ -33,16 +34,23 @@ import java.util.List; import java.util.NoSuchElementException; -public class VectorCodec implements TypeCodec> { +public class VectorCodec implements TypeCodec> { - private final VectorType cqlType; + protected final VectorType cqlType; private final GenericType> javaType; - private final TypeCodec subtypeCodec; + protected final TypeCodec subtypeCodec; + + private final VectorCodec proxyCodec; public VectorCodec(@NonNull VectorType cqlType, @NonNull TypeCodec subtypeCodec) { this.cqlType = cqlType; this.subtypeCodec = subtypeCodec; this.javaType = GenericType.vectorOf(subtypeCodec.getJavaType()); + if (subtypeCodec.serializedSize().isPresent()) { + this.proxyCodec = new FixedLength<>(cqlType, subtypeCodec); + } else { + this.proxyCodec = new VariableLength<>(cqlType, subtypeCodec); + } } public VectorCodec(int dimensions, @NonNull TypeCodec subtypeCodec) { @@ -65,82 +73,14 @@ public DataType getCqlType() { @Override public ByteBuffer encode( @Nullable CqlVector value, @NonNull ProtocolVersion protocolVersion) { - if (value == null || cqlType.getDimensions() <= 0) { - return null; - } - ByteBuffer[] valueBuffs = new ByteBuffer[cqlType.getDimensions()]; - Iterator values = value.iterator(); - int allValueBuffsSize = 0; - for (int i = 0; i < cqlType.getDimensions(); ++i) { - ByteBuffer valueBuff; - SubtypeT valueObj; - - try { - valueObj = values.next(); - } catch (NoSuchElementException nsee) { - throw new IllegalArgumentException( - String.format( - "Not enough elements; must provide elements for %d dimensions", - cqlType.getDimensions())); - } - - try { - valueBuff = this.subtypeCodec.encode(valueObj, protocolVersion); - } catch (ClassCastException e) { - throw new IllegalArgumentException("Invalid type for element: " + valueObj.getClass()); - } - if (valueBuff == null) { - throw new NullPointerException("Vector elements cannot encode to CQL NULL"); - } - allValueBuffsSize += valueBuff.limit(); - valueBuff.rewind(); - valueBuffs[i] = valueBuff; - } - /* Since we already did an early return for <= 0 dimensions above */ - assert valueBuffs.length > 0; - ByteBuffer rv = ByteBuffer.allocate(allValueBuffsSize); - for (int i = 0; i < cqlType.getDimensions(); ++i) { - rv.put(valueBuffs[i]); - } - rv.flip(); - return rv; + return this.proxyCodec.encode(value, protocolVersion); } @Nullable @Override public CqlVector decode( @Nullable ByteBuffer bytes, @NonNull ProtocolVersion protocolVersion) { - if (bytes == null || bytes.remaining() == 0) { - return null; - } - - /* Determine element size by dividing count of remaining bytes by number of elements. This should have a remainder - of zero if we assume all elements are of uniform size (which is really a terrible assumption). - - TODO: We should probably tweak serialization format for vectors if we're going to allow them for arbitrary subtypes. - Elements should at least precede themselves with their size (along the lines of what lists do). */ - int elementSize = Math.floorDiv(bytes.remaining(), cqlType.getDimensions()); - if (!(bytes.remaining() % cqlType.getDimensions() == 0)) { - throw new IllegalArgumentException( - String.format( - "Expected elements of uniform size, observed %d elements with total bytes %d", - cqlType.getDimensions(), bytes.remaining())); - } - - ByteBuffer slice = bytes.slice(); - List rv = new ArrayList(cqlType.getDimensions()); - for (int i = 0; i < cqlType.getDimensions(); ++i) { - // Set the limit for the current element - int originalPosition = slice.position(); - slice.limit(originalPosition + elementSize); - rv.add(this.subtypeCodec.decode(slice, protocolVersion)); - // Move to the start of the next element - slice.position(originalPosition + elementSize); - // Reset the limit to the end of the buffer - slice.limit(slice.capacity()); - } - - return CqlVector.newInstance(rv); + return this.proxyCodec.decode(bytes, protocolVersion); } @NonNull @@ -156,4 +96,164 @@ public CqlVector parse(@Nullable String value) { ? null : CqlVector.from(value, this.subtypeCodec); } + + private static class FixedLength extends VectorCodec { + private FixedLength(VectorType cqlType, TypeCodec subtypeCodec) { + super(cqlType, subtypeCodec); + } + + @Override + public ByteBuffer encode( + @Nullable CqlVector value, @NonNull ProtocolVersion protocolVersion) { + if (value == null || cqlType.getDimensions() <= 0) { + return null; + } + ByteBuffer[] valueBuffs = new ByteBuffer[cqlType.getDimensions()]; + Iterator values = value.iterator(); + int allValueBuffsSize = 0; + for (int i = 0; i < cqlType.getDimensions(); ++i) { + ByteBuffer valueBuff; + SubtypeT valueObj; + + try { + valueObj = values.next(); + } catch (NoSuchElementException nsee) { + throw new IllegalArgumentException( + String.format( + "Not enough elements; must provide elements for %d dimensions", + cqlType.getDimensions())); + } + + try { + valueBuff = this.subtypeCodec.encode(valueObj, protocolVersion); + } catch (ClassCastException e) { + throw new IllegalArgumentException("Invalid type for element: " + valueObj.getClass()); + } + if (valueBuff == null) { + throw new NullPointerException("Vector elements cannot encode to CQL NULL"); + } + allValueBuffsSize += valueBuff.limit(); + valueBuff.rewind(); + valueBuffs[i] = valueBuff; + } + /* Since we already did an early return for <= 0 dimensions above */ + assert valueBuffs.length > 0; + ByteBuffer rv = ByteBuffer.allocate(allValueBuffsSize); + for (int i = 0; i < cqlType.getDimensions(); ++i) { + rv.put(valueBuffs[i]); + } + rv.flip(); + return rv; + } + + @Override + public CqlVector decode( + @Nullable ByteBuffer bytes, @NonNull ProtocolVersion protocolVersion) { + if (bytes == null || bytes.remaining() == 0) { + return null; + } + + int elementSize = Math.floorDiv(bytes.remaining(), cqlType.getDimensions()); + if (!(bytes.remaining() % cqlType.getDimensions() == 0)) { + throw new IllegalArgumentException( + String.format( + "Expected elements of uniform size, observed %d elements with total bytes %d", + cqlType.getDimensions(), bytes.remaining())); + } + + ByteBuffer slice = bytes.slice(); + List rv = new ArrayList(cqlType.getDimensions()); + for (int i = 0; i < cqlType.getDimensions(); ++i) { + // Set the limit for the current element + int originalPosition = slice.position(); + slice.limit(originalPosition + elementSize); + rv.add(this.subtypeCodec.decode(slice, protocolVersion)); + // Move to the start of the next element + slice.position(originalPosition + elementSize); + // Reset the limit to the end of the buffer + slice.limit(slice.capacity()); + } + + return CqlVector.newInstance(rv); + } + } + + private static class VariableLength extends VectorCodec { + private VariableLength(VectorType cqlType, TypeCodec subtypeCodec) { + super(cqlType, subtypeCodec); + } + + @Override + public ByteBuffer encode( + @Nullable CqlVector value, @NonNull ProtocolVersion protocolVersion) { + if (value == null || cqlType.getDimensions() <= 0) { + return null; + } + ByteBuffer[] valueBuffs = new ByteBuffer[cqlType.getDimensions()]; + Iterator values = value.iterator(); + int allValueBuffsSize = 0; + for (int i = 0; i < cqlType.getDimensions(); ++i) { + ByteBuffer valueBuff; + SubtypeT valueObj; + + try { + valueObj = values.next(); + } catch (NoSuchElementException nsee) { + throw new IllegalArgumentException( + String.format( + "Not enough elements; must provide elements for %d dimensions", + cqlType.getDimensions())); + } + + try { + valueBuff = this.subtypeCodec.encode(valueObj, protocolVersion); + } catch (ClassCastException e) { + throw new IllegalArgumentException("Invalid type for element: " + valueObj.getClass()); + } + if (valueBuff == null) { + throw new NullPointerException("Vector elements cannot encode to CQL NULL"); + } + int elementSize = valueBuff.limit(); + allValueBuffsSize += elementSize + VIntCoding.computeVIntSize(elementSize); + valueBuff.rewind(); + valueBuffs[i] = valueBuff; + } + /* Since we already did an early return for <= 0 dimensions above */ + assert valueBuffs.length > 0; + ByteBuffer rv = ByteBuffer.allocate(allValueBuffsSize); + for (int i = 0; i < cqlType.getDimensions(); ++i) { + VIntCoding.writeUnsignedVInt32(valueBuffs[i].remaining(), rv); + rv.put(valueBuffs[i]); + } + rv.flip(); + return rv; + } + + @Override + public CqlVector decode( + @Nullable ByteBuffer bytes, @NonNull ProtocolVersion protocolVersion) { + if (bytes == null || bytes.remaining() == 0) { + return null; + } + + ByteBuffer input = bytes.duplicate(); + List rv = new ArrayList(cqlType.getDimensions()); + for (int i = 0; i < cqlType.getDimensions(); ++i) { + int size = VIntCoding.getUnsignedVInt32(input, input.position()); + input.position(input.position() + VIntCoding.computeUnsignedVIntSize(size)); + + ByteBuffer value; + if (size < 0) { + value = null; + } else { + value = input.duplicate(); + value.limit(value.position() + size); + input.position(input.position() + size); + } + rv.add(subtypeCodec.decode(value, protocolVersion)); + } + + return CqlVector.newInstance(rv); + } + } } diff --git a/core/src/main/java/com/datastax/oss/driver/internal/core/type/codec/extras/time/TimestampMillisCodec.java b/core/src/main/java/com/datastax/oss/driver/internal/core/type/codec/extras/time/TimestampMillisCodec.java index a15495a432d..598b8b16243 100644 --- a/core/src/main/java/com/datastax/oss/driver/internal/core/type/codec/extras/time/TimestampMillisCodec.java +++ b/core/src/main/java/com/datastax/oss/driver/internal/core/type/codec/extras/time/TimestampMillisCodec.java @@ -25,6 +25,7 @@ import com.datastax.oss.driver.api.core.type.codec.TypeCodecs; import com.datastax.oss.driver.api.core.type.reflect.GenericType; import com.datastax.oss.driver.internal.core.type.codec.TimestampCodec; +import com.datastax.oss.driver.shaded.guava.common.base.Optional; import edu.umd.cs.findbugs.annotations.NonNull; import edu.umd.cs.findbugs.annotations.Nullable; import java.nio.ByteBuffer; @@ -114,4 +115,10 @@ public String format(@Nullable Long value) { Instant instant = value == null ? null : Instant.ofEpochMilli(value); return timestampCodec.format(instant); } + + @NonNull + @Override + public Optional serializedSize() { + return Optional.of(8); + } } diff --git a/core/src/main/java/com/datastax/oss/driver/internal/core/type/util/VIntCoding.java b/core/src/main/java/com/datastax/oss/driver/internal/core/type/util/VIntCoding.java index 5ee375a81e5..552f84f2ae1 100644 --- a/core/src/main/java/com/datastax/oss/driver/internal/core/type/util/VIntCoding.java +++ b/core/src/main/java/com/datastax/oss/driver/internal/core/type/util/VIntCoding.java @@ -49,6 +49,7 @@ import java.io.DataInput; import java.io.DataOutput; import java.io.IOException; +import java.nio.ByteBuffer; /** * Variable length encoding inspired from Google > 6; } + + public static void writeUnsignedVInt32(int value, ByteBuffer output) { + writeUnsignedVInt((long) value, output); + } + + public static void writeUnsignedVInt(long value, ByteBuffer output) { + int size = VIntCoding.computeUnsignedVIntSize(value); + if (size == 1) { + output.put((byte) value); + return; + } + + output.put(VIntCoding.encodeVInt(value, size), 0, size); + } + + /** + * Read up to a 32-bit integer back, using the unsigned (no zigzag) encoding. + * + *

Note this method is the same as {@link #readUnsignedVInt(DataInput)}, except that we do + * *not* block if there are not enough bytes in the buffer to reconstruct the value. + * + * @throws VIntOutOfRangeException If the vint doesn't fit into a 32-bit integer + */ + public static int getUnsignedVInt32(ByteBuffer input, int readerIndex) { + return checkedCast(getUnsignedVInt(input, readerIndex)); + } + + public static long getUnsignedVInt(ByteBuffer input, int readerIndex) { + return getUnsignedVInt(input, readerIndex, input.limit()); + } + + public static long getUnsignedVInt(ByteBuffer input, int readerIndex, int readerLimit) { + if (readerIndex < 0) + throw new IllegalArgumentException( + "Reader index should be non-negative, but was " + readerIndex); + + if (readerIndex >= readerLimit) return -1; + + int firstByte = input.get(readerIndex++); + + // Bail out early if this is one byte, necessary or it fails later + if (firstByte >= 0) return firstByte; + + int size = numberOfExtraBytesToRead(firstByte); + if (readerIndex + size > readerLimit) return -1; + + long retval = firstByte & firstByteValueMask(size); + for (int ii = 0; ii < size; ii++) { + byte b = input.get(readerIndex++); + retval <<= 8; + retval |= b & 0xff; + } + + return retval; + } + + public static int checkedCast(long value) { + int result = (int) value; + if ((long) result != value) throw new VIntOutOfRangeException(value); + return result; + } + + /** + * Throw when attempting to decode a vint and the output type doesn't have enough space to fit the + * value that was decoded + */ + public static class VIntOutOfRangeException extends RuntimeException { + public final long value; + + private VIntOutOfRangeException(long value) { + super(value + " is out of range for a 32-bit integer"); + this.value = value; + } + } } From 5d0087e90a3d70f2aeb02257b26ed48ee57f2fee Mon Sep 17 00:00:00 2001 From: janehe Date: Tue, 20 Aug 2024 17:28:31 -0800 Subject: [PATCH 11/24] fix circle --- .../internal/core/type/codec/VectorCodec.java | 28 +++++++++++++++---- 1 file changed, 23 insertions(+), 5 deletions(-) diff --git a/core/src/main/java/com/datastax/oss/driver/internal/core/type/codec/VectorCodec.java b/core/src/main/java/com/datastax/oss/driver/internal/core/type/codec/VectorCodec.java index 04dbf50c681..128388cdabc 100644 --- a/core/src/main/java/com/datastax/oss/driver/internal/core/type/codec/VectorCodec.java +++ b/core/src/main/java/com/datastax/oss/driver/internal/core/type/codec/VectorCodec.java @@ -40,7 +40,7 @@ public class VectorCodec implements TypeCodec> { private final GenericType> javaType; protected final TypeCodec subtypeCodec; - private final VectorCodec proxyCodec; + private final VectorCodecProxy proxyCodec; public VectorCodec(@NonNull VectorType cqlType, @NonNull TypeCodec subtypeCodec) { this.cqlType = cqlType; @@ -69,6 +69,16 @@ public DataType getCqlType() { return this.cqlType; } + private interface VectorCodecProxy { + @Nullable + ByteBuffer encode( + @Nullable CqlVector value, @NonNull ProtocolVersion protocolVersion); + + @Nullable + CqlVector decode( + @Nullable ByteBuffer bytes, @NonNull ProtocolVersion protocolVersion); + } + @Nullable @Override public ByteBuffer encode( @@ -97,9 +107,13 @@ public CqlVector parse(@Nullable String value) { : CqlVector.from(value, this.subtypeCodec); } - private static class FixedLength extends VectorCodec { + private static class FixedLength implements VectorCodecProxy { + private final VectorType cqlType; + private final TypeCodec subtypeCodec; + private FixedLength(VectorType cqlType, TypeCodec subtypeCodec) { - super(cqlType, subtypeCodec); + this.cqlType = cqlType; + this.subtypeCodec = subtypeCodec; } @Override @@ -178,9 +192,13 @@ public CqlVector decode( } } - private static class VariableLength extends VectorCodec { + private static class VariableLength implements VectorCodecProxy { + private final VectorType cqlType; + private final TypeCodec subtypeCodec; + private VariableLength(VectorType cqlType, TypeCodec subtypeCodec) { - super(cqlType, subtypeCodec); + this.cqlType = cqlType; + this.subtypeCodec = subtypeCodec; } @Override From 3f75dd8ca7009346884fb211b944ba7d3f0ae7be Mon Sep 17 00:00:00 2001 From: janehe Date: Wed, 21 Aug 2024 10:59:18 -0800 Subject: [PATCH 12/24] tinyint works --- .../internal/core/type/codec/VectorCodec.java | 14 ++++++++++++-- .../datastax/oss/driver/core/data/DataTypeIT.java | 5 +++-- 2 files changed, 15 insertions(+), 4 deletions(-) diff --git a/core/src/main/java/com/datastax/oss/driver/internal/core/type/codec/VectorCodec.java b/core/src/main/java/com/datastax/oss/driver/internal/core/type/codec/VectorCodec.java index 128388cdabc..a056ccdea4d 100644 --- a/core/src/main/java/com/datastax/oss/driver/internal/core/type/codec/VectorCodec.java +++ b/core/src/main/java/com/datastax/oss/driver/internal/core/type/codec/VectorCodec.java @@ -33,6 +33,7 @@ import java.util.Iterator; import java.util.List; import java.util.NoSuchElementException; +import java.util.stream.Collectors; public class VectorCodec implements TypeCodec> { @@ -95,8 +96,17 @@ public CqlVector decode( @NonNull @Override - public String format(@Nullable CqlVector value) { - return value == null ? "NULL" : Iterables.toString(value); + public String format(CqlVector value) { + if (value == null) return "NULL"; + + // if the subtype is a string, double quote + if (!value.isEmpty() && value.iterator().next() instanceof String) + return value.stream() + .map(s -> (String) s) + .map(s -> "\"" + s + "\"") + .collect(Collectors.joining(", ", "[", "]")); + + return Iterables.toString(value); } @Nullable diff --git a/integration-tests/src/test/java/com/datastax/oss/driver/core/data/DataTypeIT.java b/integration-tests/src/test/java/com/datastax/oss/driver/core/data/DataTypeIT.java index 3a1a9816fb6..9c1b6d79310 100644 --- a/integration-tests/src/test/java/com/datastax/oss/driver/core/data/DataTypeIT.java +++ b/integration-tests/src/test/java/com/datastax/oss/driver/core/data/DataTypeIT.java @@ -46,6 +46,7 @@ import com.datastax.oss.driver.api.core.type.TupleType; import com.datastax.oss.driver.api.core.type.UserDefinedType; import com.datastax.oss.driver.api.core.type.codec.TypeCodec; +import com.datastax.oss.driver.api.core.type.reflect.GenericType; import com.datastax.oss.driver.api.testinfra.ccm.CcmRule; import com.datastax.oss.driver.api.testinfra.session.SessionRule; import com.datastax.oss.driver.categories.ParallelizableTests; @@ -266,8 +267,8 @@ public static Object[][] typeSamples() { // change the vector subtype into arbitrary type if (o[0] == DataTypes.INT) { - CqlVector vector = CqlVector.newInstance(1.1f, 2.2f, 3.3f); - samples.add(new Object[] {DataTypes.vectorOf(DataTypes.FLOAT, 3), vector}); + CqlVector vector = CqlVector.newInstance((byte) 1, (byte) 2, (byte) 3); + samples.add(new Object[] {DataTypes.vectorOf(DataTypes.TINYINT, 3), vector}); } return samples.stream(); }) From ae14fa489db6e997b2bcaf1e24b646e63e9cbf4e Mon Sep 17 00:00:00 2001 From: janehe Date: Wed, 21 Aug 2024 11:14:34 -0800 Subject: [PATCH 13/24] adding integration tests of vector in all subtypes --- .../com/datastax/oss/driver/core/data/DataTypeIT.java | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/integration-tests/src/test/java/com/datastax/oss/driver/core/data/DataTypeIT.java b/integration-tests/src/test/java/com/datastax/oss/driver/core/data/DataTypeIT.java index 9c1b6d79310..7b2baeff2e1 100644 --- a/integration-tests/src/test/java/com/datastax/oss/driver/core/data/DataTypeIT.java +++ b/integration-tests/src/test/java/com/datastax/oss/driver/core/data/DataTypeIT.java @@ -265,11 +265,10 @@ public static Object[][] typeSamples() { UdtValue udtValue2 = udt.newValue(1, o[1]); samples.add(new Object[] {udt, udtValue2}); - // change the vector subtype into arbitrary type - if (o[0] == DataTypes.INT) { - CqlVector vector = CqlVector.newInstance((byte) 1, (byte) 2, (byte) 3); - samples.add(new Object[] {DataTypes.vectorOf(DataTypes.TINYINT, 3), vector}); - } + // vector of type + CqlVector vector = CqlVector.newInstance(o[1]); + samples.add(new Object[] {DataTypes.vectorOf(dataType, 1), vector}); + return samples.stream(); }) .toArray(Object[][]::new); From 522fab825541ec96e8706bc5c6388cdce3366bc9 Mon Sep 17 00:00:00 2001 From: janehe Date: Wed, 21 Aug 2024 13:47:29 -0800 Subject: [PATCH 14/24] all tests passed --- .../internal/core/type/codec/DateCodec.java | 2 +- .../internal/core/type/codec/TimeCodec.java | 2 +- .../internal/core/type/codec/VectorCodec.java | 16 ++++++++-------- .../oss/driver/core/data/DataTypeIT.java | 8 +++++--- 4 files changed, 15 insertions(+), 13 deletions(-) diff --git a/core/src/main/java/com/datastax/oss/driver/internal/core/type/codec/DateCodec.java b/core/src/main/java/com/datastax/oss/driver/internal/core/type/codec/DateCodec.java index da499687ef8..84b0722af26 100644 --- a/core/src/main/java/com/datastax/oss/driver/internal/core/type/codec/DateCodec.java +++ b/core/src/main/java/com/datastax/oss/driver/internal/core/type/codec/DateCodec.java @@ -157,6 +157,6 @@ private static int cqlDateToDaysSinceEpoch(long raw) { @NonNull @Override public Optional serializedSize() { - return Optional.of(8); + return Optional.absent(); } } diff --git a/core/src/main/java/com/datastax/oss/driver/internal/core/type/codec/TimeCodec.java b/core/src/main/java/com/datastax/oss/driver/internal/core/type/codec/TimeCodec.java index 2295adfae6a..a88d2838200 100644 --- a/core/src/main/java/com/datastax/oss/driver/internal/core/type/codec/TimeCodec.java +++ b/core/src/main/java/com/datastax/oss/driver/internal/core/type/codec/TimeCodec.java @@ -118,6 +118,6 @@ public LocalTime parse(@Nullable String value) { @NonNull @Override public Optional serializedSize() { - return Optional.of(8); + return Optional.absent(); } } diff --git a/core/src/main/java/com/datastax/oss/driver/internal/core/type/codec/VectorCodec.java b/core/src/main/java/com/datastax/oss/driver/internal/core/type/codec/VectorCodec.java index a056ccdea4d..727f06854b2 100644 --- a/core/src/main/java/com/datastax/oss/driver/internal/core/type/codec/VectorCodec.java +++ b/core/src/main/java/com/datastax/oss/driver/internal/core/type/codec/VectorCodec.java @@ -28,7 +28,12 @@ import com.datastax.oss.driver.shaded.guava.common.collect.Iterables; import edu.umd.cs.findbugs.annotations.NonNull; import edu.umd.cs.findbugs.annotations.Nullable; + +import java.net.InetAddress; import java.nio.ByteBuffer; +import java.time.Instant; +import java.time.LocalDate; +import java.time.LocalTime; import java.util.ArrayList; import java.util.Iterator; import java.util.List; @@ -99,14 +104,9 @@ public CqlVector decode( public String format(CqlVector value) { if (value == null) return "NULL"; - // if the subtype is a string, double quote - if (!value.isEmpty() && value.iterator().next() instanceof String) - return value.stream() - .map(s -> (String) s) - .map(s -> "\"" + s + "\"") - .collect(Collectors.joining(", ", "[", "]")); - - return Iterables.toString(value); + return value.stream() + .map(subtypeCodec::format) + .collect(Collectors.joining(", ", "[", "]")); } @Nullable diff --git a/integration-tests/src/test/java/com/datastax/oss/driver/core/data/DataTypeIT.java b/integration-tests/src/test/java/com/datastax/oss/driver/core/data/DataTypeIT.java index 7b2baeff2e1..b02472e5d94 100644 --- a/integration-tests/src/test/java/com/datastax/oss/driver/core/data/DataTypeIT.java +++ b/integration-tests/src/test/java/com/datastax/oss/driver/core/data/DataTypeIT.java @@ -265,9 +265,11 @@ public static Object[][] typeSamples() { UdtValue udtValue2 = udt.newValue(1, o[1]); samples.add(new Object[] {udt, udtValue2}); - // vector of type - CqlVector vector = CqlVector.newInstance(o[1]); - samples.add(new Object[] {DataTypes.vectorOf(dataType, 1), vector}); + if (CCM_RULE.getCassandraVersion().compareTo(Version.parse("5.0")) >= 0){ + // vector of type + CqlVector vector = CqlVector.newInstance(o[1]); + samples.add(new Object[] {DataTypes.vectorOf(dataType, 1), vector}); + } return samples.stream(); }) From 61bdf29b1254cf0a940f43946abff7d6d1163af0 Mon Sep 17 00:00:00 2001 From: janehe Date: Wed, 21 Aug 2024 22:38:54 -0800 Subject: [PATCH 15/24] nested vector passed --- .../oss/driver/api/core/type/DataTypes.java | 20 +++++++++++++------ .../internal/core/type/codec/VectorCodec.java | 6 ++++++ ...CachingCodecRegistryTestDataProviders.java | 5 +++++ .../oss/driver/core/data/DataTypeIT.java | 5 +++++ 4 files changed, 30 insertions(+), 6 deletions(-) diff --git a/core/src/main/java/com/datastax/oss/driver/api/core/type/DataTypes.java b/core/src/main/java/com/datastax/oss/driver/api/core/type/DataTypes.java index 3a341eaa5aa..ce05649d8c7 100644 --- a/core/src/main/java/com/datastax/oss/driver/api/core/type/DataTypes.java +++ b/core/src/main/java/com/datastax/oss/driver/api/core/type/DataTypes.java @@ -69,12 +69,20 @@ public static DataType custom(@NonNull String className) { /* Vector support is currently implemented as a custom type but is also parameterized */ if (className.startsWith(DefaultVectorType.VECTOR_CLASS_NAME)) { - List params = - paramSplitter.splitToList( - className.substring( - DefaultVectorType.VECTOR_CLASS_NAME.length() + 1, className.length() - 1)); - DataType subType = classNameParser.parse(params.get(0), AttachmentPoint.NONE); - int dimensions = Integer.parseInt(params.get(1)); + String paramsString = className.substring( + DefaultVectorType.VECTOR_CLASS_NAME.length() + 1, className.length() - 1); + int lastCommaIndex = paramsString.lastIndexOf(','); + if (lastCommaIndex == -1) { + throw new IllegalArgumentException( + String.format( + "Invalid vector type %s, expected format is %s", + className, DefaultVectorType.VECTOR_CLASS_NAME)); + } + String subTypeString = paramsString.substring(0, lastCommaIndex).trim(); + String dimensionsString = paramsString.substring(lastCommaIndex + 1).trim(); + + DataType subType = classNameParser.parse(subTypeString, AttachmentPoint.NONE); + int dimensions = Integer.parseInt(dimensionsString); if (dimensions <= 0) { throw new IllegalArgumentException( String.format( diff --git a/core/src/main/java/com/datastax/oss/driver/internal/core/type/codec/VectorCodec.java b/core/src/main/java/com/datastax/oss/driver/internal/core/type/codec/VectorCodec.java index 727f06854b2..71dfefe80ce 100644 --- a/core/src/main/java/com/datastax/oss/driver/internal/core/type/codec/VectorCodec.java +++ b/core/src/main/java/com/datastax/oss/driver/internal/core/type/codec/VectorCodec.java @@ -25,6 +25,7 @@ import com.datastax.oss.driver.api.core.type.reflect.GenericType; import com.datastax.oss.driver.internal.core.type.DefaultVectorType; import com.datastax.oss.driver.internal.core.type.util.VIntCoding; +import com.datastax.oss.driver.shaded.guava.common.base.Optional; import com.datastax.oss.driver.shaded.guava.common.collect.Iterables; import edu.umd.cs.findbugs.annotations.NonNull; import edu.umd.cs.findbugs.annotations.Nullable; @@ -69,6 +70,11 @@ public GenericType> getJavaType() { return this.javaType; } + @NonNull + public Optional serializedSize(){ + return subtypeCodec.serializedSize().isPresent() ? Optional.of(subtypeCodec.serializedSize().get() * cqlType.getDimensions()) : Optional.absent(); + } + @NonNull @Override public DataType getCqlType() { diff --git a/core/src/test/java/com/datastax/oss/driver/internal/core/type/codec/registry/CachingCodecRegistryTestDataProviders.java b/core/src/test/java/com/datastax/oss/driver/internal/core/type/codec/registry/CachingCodecRegistryTestDataProviders.java index 1f3f6bbff97..cc867de0c35 100644 --- a/core/src/test/java/com/datastax/oss/driver/internal/core/type/codec/registry/CachingCodecRegistryTestDataProviders.java +++ b/core/src/test/java/com/datastax/oss/driver/internal/core/type/codec/registry/CachingCodecRegistryTestDataProviders.java @@ -337,6 +337,11 @@ public static Object[][] collectionsWithCqlAndJavaTypes() GenericType.vectorOf(BigInteger.class), CqlVector.newInstance(BigInteger.ONE) }, +// // vector with arbitrary types +// { +// DataTypes.vectorOf(DataTypes.listOf(DataTypes.INT), 1), +// +// } }; } diff --git a/integration-tests/src/test/java/com/datastax/oss/driver/core/data/DataTypeIT.java b/integration-tests/src/test/java/com/datastax/oss/driver/core/data/DataTypeIT.java index b02472e5d94..9ea29bd773b 100644 --- a/integration-tests/src/test/java/com/datastax/oss/driver/core/data/DataTypeIT.java +++ b/integration-tests/src/test/java/com/datastax/oss/driver/core/data/DataTypeIT.java @@ -271,6 +271,11 @@ public static Object[][] typeSamples() { samples.add(new Object[] {DataTypes.vectorOf(dataType, 1), vector}); } + if (o[1].equals("ascii")){ + // once + CqlVector vector = CqlVector.newInstance(CqlVector.newInstance(1, 2)); + samples.add(new Object[] {DataTypes.vectorOf(DataTypes.vectorOf(DataTypes.INT, 2), 1), vector}); + } return samples.stream(); }) .toArray(Object[][]::new); From d2ff14516acfb7bb1c1ce69d01d26bd7e25d6398 Mon Sep 17 00:00:00 2001 From: janehe Date: Wed, 21 Aug 2024 22:53:43 -0800 Subject: [PATCH 16/24] add vectors of all types --- .../oss/driver/core/data/DataTypeIT.java | 31 +++++++++++++++---- 1 file changed, 25 insertions(+), 6 deletions(-) diff --git a/integration-tests/src/test/java/com/datastax/oss/driver/core/data/DataTypeIT.java b/integration-tests/src/test/java/com/datastax/oss/driver/core/data/DataTypeIT.java index 9ea29bd773b..95bdface17d 100644 --- a/integration-tests/src/test/java/com/datastax/oss/driver/core/data/DataTypeIT.java +++ b/integration-tests/src/test/java/com/datastax/oss/driver/core/data/DataTypeIT.java @@ -18,6 +18,7 @@ package com.datastax.oss.driver.core.data; import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.InstanceOfAssertFactories.type; import static org.junit.Assert.fail; import com.datastax.oss.driver.api.core.CqlIdentifier; @@ -185,6 +186,7 @@ public static Object[][] typeSamples() { // 5) include map // 6) include tuple // 7) include udt + // 8) include vector return Arrays.stream(primitiveSamples) .flatMap( o -> { @@ -281,6 +283,23 @@ public static Object[][] typeSamples() { .toArray(Object[][]::new); } + @DataProvider + public static Object[][] addVectors(){ + Object[][] previousSamples = typeSamples(); + if (CCM_RULE.getCassandraVersion().compareTo(Version.parse("5.0")) < 0) return previousSamples; + return Arrays.stream(previousSamples).flatMap( + o -> { + List samples = new ArrayList<>(); + samples.add(o); + if (o[1] == null) return samples.stream(); + DataType dataType = (DataType) o[0]; + CqlVector vector = CqlVector.newInstance(o[1]); + samples.add(new Object[] {DataTypes.vectorOf(dataType, 1), vector}); + return samples.stream(); + }).toArray(Object[][]::new); + } + + @BeforeClass public static void createTable() { // Create a table with all types being tested with. @@ -291,7 +310,7 @@ public static void createTable() { List columnData = new ArrayList<>(); - for (Object[] sample : typeSamples()) { + for (Object[] sample : addVectors()) { DataType dataType = (DataType) sample[0]; if (!typeToColumnName.containsKey(dataType)) { @@ -321,7 +340,7 @@ private static int nextKey() { return keyCounter.incrementAndGet(); } - @UseDataProvider("typeSamples") + @UseDataProvider("addVectors") @Test public void should_insert_non_primary_key_column_simple_statement_using_format( DataType dataType, K value, K expectedPrimitiveValue) { @@ -348,7 +367,7 @@ public void should_insert_non_primary_key_column_simple_statement_using_form readValue(select, dataType, value, expectedPrimitiveValue); } - @UseDataProvider("typeSamples") + @UseDataProvider("addVectors") @Test public void should_insert_non_primary_key_column_simple_statement_positional_value( DataType dataType, K value, K expectedPrimitiveValue) { @@ -371,7 +390,7 @@ public void should_insert_non_primary_key_column_simple_statement_positional readValue(select, dataType, value, expectedPrimitiveValue); } - @UseDataProvider("typeSamples") + @UseDataProvider("addVectors") @Test public void should_insert_non_primary_key_column_simple_statement_named_value( DataType dataType, K value, K expectedPrimitiveValue) { @@ -395,7 +414,7 @@ public void should_insert_non_primary_key_column_simple_statement_named_valu readValue(select, dataType, value, expectedPrimitiveValue); } - @UseDataProvider("typeSamples") + @UseDataProvider("addVectors") @Test public void should_insert_non_primary_key_column_bound_statement_positional_value( DataType dataType, K value, K expectedPrimitiveValue) { @@ -424,7 +443,7 @@ public void should_insert_non_primary_key_column_bound_statement_positional_ readValue(boundSelect, dataType, value, expectedPrimitiveValue); } - @UseDataProvider("typeSamples") + @UseDataProvider("addVectors") @Test public void should_insert_non_primary_key_column_bound_statement_named_value( DataType dataType, K value, K expectedPrimitiveValue) { From 6422932db683d0377321db04dccad2cb472777ee Mon Sep 17 00:00:00 2001 From: janehe Date: Thu, 29 Aug 2024 08:07:37 -0800 Subject: [PATCH 17/24] add a ton of unit tests --- .../oss/driver/api/core/data/CqlVector.java | 51 +++- .../oss/driver/api/core/type/DataTypes.java | 4 +- .../internal/core/type/DefaultVectorType.java | 2 +- .../internal/core/type/codec/VectorCodec.java | 43 +++- .../core/type/codec/VectorCodecTest.java | 227 ++++++++++++++---- ...CachingCodecRegistryTestDataProviders.java | 25 +- .../oss/driver/core/data/DataTypeIT.java | 34 ++- 7 files changed, 288 insertions(+), 98 deletions(-) diff --git a/core/src/main/java/com/datastax/oss/driver/api/core/data/CqlVector.java b/core/src/main/java/com/datastax/oss/driver/api/core/data/CqlVector.java index f98da5cc504..2014119444e 100644 --- a/core/src/main/java/com/datastax/oss/driver/api/core/data/CqlVector.java +++ b/core/src/main/java/com/datastax/oss/driver/api/core/data/CqlVector.java @@ -18,11 +18,10 @@ package com.datastax.oss.driver.api.core.data; import com.datastax.oss.driver.api.core.type.codec.TypeCodec; +import com.datastax.oss.driver.internal.core.type.codec.ParseUtils; import com.datastax.oss.driver.shaded.guava.common.base.Preconditions; import com.datastax.oss.driver.shaded.guava.common.base.Predicates; -import com.datastax.oss.driver.shaded.guava.common.base.Splitter; import com.datastax.oss.driver.shaded.guava.common.collect.Iterables; -import com.datastax.oss.driver.shaded.guava.common.collect.Streams; import edu.umd.cs.findbugs.annotations.NonNull; import java.io.IOException; import java.io.InvalidObjectException; @@ -35,7 +34,6 @@ import java.util.Iterator; import java.util.List; import java.util.Objects; -import java.util.stream.Collectors; import java.util.stream.Stream; /** @@ -90,11 +88,48 @@ public static CqlVector newInstance(List list) { public static CqlVector from(@NonNull String str, @NonNull TypeCodec subtypeCodec) { Preconditions.checkArgument(str != null, "Cannot create CqlVector from null string"); Preconditions.checkArgument(!str.isEmpty(), "Cannot create CqlVector from empty string"); - ArrayList vals = - Streams.stream(Splitter.on(", ").split(str.substring(1, str.length() - 1))) - .map(subtypeCodec::parse) - .collect(Collectors.toCollection(ArrayList::new)); - return new CqlVector(vals); + if (str == null || str.isEmpty() || str.equalsIgnoreCase("NULL")) return null; + + int idx = ParseUtils.skipSpaces(str, 0); + if (str.charAt(idx++) != '[') + throw new IllegalArgumentException( + String.format( + "Cannot parse list value from \"%s\", at character %d expecting '[' but got '%c'", + str, idx, str.charAt(idx))); + + idx = ParseUtils.skipSpaces(str, idx); + + if (str.charAt(idx) == ']') { + return null; + } + + List list = new ArrayList<>(); + while (idx < str.length()) { + int n; + try { + n = ParseUtils.skipCQLValue(str, idx); + } catch (IllegalArgumentException e) { + throw new IllegalArgumentException( + String.format( + "Cannot parse list value from \"%s\", invalid CQL value at character %d", str, idx), + e); + } + + list.add(subtypeCodec.parse(str.substring(idx, n))); + idx = n; + + idx = ParseUtils.skipSpaces(str, idx); + if (str.charAt(idx) == ']') return new CqlVector<>(list); + if (str.charAt(idx++) != ',') + throw new IllegalArgumentException( + String.format( + "Cannot parse list value from \"%s\", at character %d expecting ',' but got '%c'", + str, idx, str.charAt(idx))); + + idx = ParseUtils.skipSpaces(str, idx); + } + throw new IllegalArgumentException( + String.format("Malformed list value \"%s\", missing closing ']'", str)); } private final List list; diff --git a/core/src/main/java/com/datastax/oss/driver/api/core/type/DataTypes.java b/core/src/main/java/com/datastax/oss/driver/api/core/type/DataTypes.java index ce05649d8c7..a08f68a8557 100644 --- a/core/src/main/java/com/datastax/oss/driver/api/core/type/DataTypes.java +++ b/core/src/main/java/com/datastax/oss/driver/api/core/type/DataTypes.java @@ -32,7 +32,6 @@ import com.datastax.oss.protocol.internal.ProtocolConstants; import edu.umd.cs.findbugs.annotations.NonNull; import java.util.Arrays; -import java.util.List; /** Constants and factory methods to obtain data type instances. */ public class DataTypes { @@ -69,7 +68,8 @@ public static DataType custom(@NonNull String className) { /* Vector support is currently implemented as a custom type but is also parameterized */ if (className.startsWith(DefaultVectorType.VECTOR_CLASS_NAME)) { - String paramsString = className.substring( + String paramsString = + className.substring( DefaultVectorType.VECTOR_CLASS_NAME.length() + 1, className.length() - 1); int lastCommaIndex = paramsString.lastIndexOf(','); if (lastCommaIndex == -1) { diff --git a/core/src/main/java/com/datastax/oss/driver/internal/core/type/DefaultVectorType.java b/core/src/main/java/com/datastax/oss/driver/internal/core/type/DefaultVectorType.java index 63cdae906be..38b5720cc1a 100644 --- a/core/src/main/java/com/datastax/oss/driver/internal/core/type/DefaultVectorType.java +++ b/core/src/main/java/com/datastax/oss/driver/internal/core/type/DefaultVectorType.java @@ -61,7 +61,7 @@ public String getClassName() { @Override public String asCql(boolean includeFrozen, boolean pretty) { return String.format( - "VECTOR<%s, %d>", this.subtype.asCql(includeFrozen, pretty).toUpperCase(), getDimensions()); + "VECTOR<%s, %d>", this.subtype.asCql(includeFrozen, pretty).toLowerCase(), getDimensions()); } /* ============== General class implementation ============== */ diff --git a/core/src/main/java/com/datastax/oss/driver/internal/core/type/codec/VectorCodec.java b/core/src/main/java/com/datastax/oss/driver/internal/core/type/codec/VectorCodec.java index 71dfefe80ce..6a97eb1eaac 100644 --- a/core/src/main/java/com/datastax/oss/driver/internal/core/type/codec/VectorCodec.java +++ b/core/src/main/java/com/datastax/oss/driver/internal/core/type/codec/VectorCodec.java @@ -26,15 +26,9 @@ import com.datastax.oss.driver.internal.core.type.DefaultVectorType; import com.datastax.oss.driver.internal.core.type.util.VIntCoding; import com.datastax.oss.driver.shaded.guava.common.base.Optional; -import com.datastax.oss.driver.shaded.guava.common.collect.Iterables; import edu.umd.cs.findbugs.annotations.NonNull; import edu.umd.cs.findbugs.annotations.Nullable; - -import java.net.InetAddress; import java.nio.ByteBuffer; -import java.time.Instant; -import java.time.LocalDate; -import java.time.LocalTime; import java.util.ArrayList; import java.util.Iterator; import java.util.List; @@ -71,8 +65,10 @@ public GenericType> getJavaType() { } @NonNull - public Optional serializedSize(){ - return subtypeCodec.serializedSize().isPresent() ? Optional.of(subtypeCodec.serializedSize().get() * cqlType.getDimensions()) : Optional.absent(); + public Optional serializedSize() { + return subtypeCodec.serializedSize().isPresent() + ? Optional.of(subtypeCodec.serializedSize().get() * cqlType.getDimensions()) + : Optional.absent(); } @NonNull @@ -110,9 +106,7 @@ public CqlVector decode( public String format(CqlVector value) { if (value == null) return "NULL"; - return value.stream() - .map(subtypeCodec::format) - .collect(Collectors.joining(", ", "[", "]")); + return value.stream().map(subtypeCodec::format).collect(Collectors.joining(", ", "[", "]")); } @Nullable @@ -166,6 +160,13 @@ public ByteBuffer encode( valueBuff.rewind(); valueBuffs[i] = valueBuff; } + // if too many elements, throw + if (values.hasNext()) { + throw new IllegalArgumentException( + String.format( + "Too many elements; must provide elements for %d dimensions", + cqlType.getDimensions())); + } /* Since we already did an early return for <= 0 dimensions above */ assert valueBuffs.length > 0; ByteBuffer rv = ByteBuffer.allocate(allValueBuffsSize); @@ -183,8 +184,8 @@ public CqlVector decode( return null; } - int elementSize = Math.floorDiv(bytes.remaining(), cqlType.getDimensions()); - if (!(bytes.remaining() % cqlType.getDimensions() == 0)) { + int elementSize = subtypeCodec.serializedSize().get(); + if (bytes.remaining() != cqlType.getDimensions() * elementSize) { throw new IllegalArgumentException( String.format( "Expected elements of uniform size, observed %d elements with total bytes %d", @@ -252,6 +253,15 @@ public ByteBuffer encode( valueBuff.rewind(); valueBuffs[i] = valueBuff; } + + // if too many elements, throw + if (values.hasNext()) { + throw new IllegalArgumentException( + String.format( + "Too many elements; must provide elements for %d dimensions", + cqlType.getDimensions())); + } + /* Since we already did an early return for <= 0 dimensions above */ assert valueBuffs.length > 0; ByteBuffer rv = ByteBuffer.allocate(allValueBuffsSize); @@ -286,6 +296,13 @@ public CqlVector decode( } rv.add(subtypeCodec.decode(value, protocolVersion)); } + // if too many elements, throw + if (input.hasRemaining()) { + throw new IllegalArgumentException( + String.format( + "Too many elements; must provide elements for %d dimensions", + cqlType.getDimensions())); + } return CqlVector.newInstance(rv); } diff --git a/core/src/test/java/com/datastax/oss/driver/internal/core/type/codec/VectorCodecTest.java b/core/src/test/java/com/datastax/oss/driver/internal/core/type/codec/VectorCodecTest.java index ee086ea2a84..2b77152c97a 100644 --- a/core/src/test/java/com/datastax/oss/driver/internal/core/type/codec/VectorCodecTest.java +++ b/core/src/test/java/com/datastax/oss/driver/internal/core/type/codec/VectorCodecTest.java @@ -20,16 +20,27 @@ import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatThrownBy; +import com.datastax.oss.driver.api.core.ProtocolVersion; import com.datastax.oss.driver.api.core.data.CqlVector; +import com.datastax.oss.driver.api.core.type.DataType; import com.datastax.oss.driver.api.core.type.DataTypes; import com.datastax.oss.driver.api.core.type.VectorType; +import com.datastax.oss.driver.api.core.type.codec.TypeCodec; import com.datastax.oss.driver.api.core.type.codec.TypeCodecs; -import com.datastax.oss.driver.api.core.type.reflect.GenericType; +import com.datastax.oss.driver.api.core.type.codec.registry.CodecRegistry; import com.datastax.oss.driver.internal.core.type.DefaultVectorType; -import java.util.Arrays; +import com.datastax.oss.protocol.internal.util.Bytes; +import com.tngtech.java.junit.dataprovider.DataProvider; +import com.tngtech.java.junit.dataprovider.DataProviderRunner; +import com.tngtech.java.junit.dataprovider.UseDataProvider; +import java.nio.ByteBuffer; +import java.time.LocalTime; +import java.util.HashMap; +import org.apache.commons.lang3.ArrayUtils; import org.junit.Test; +import org.junit.runner.RunWith; -/** Only for Float TODO: add others */ +@RunWith(DataProviderRunner.class) public class VectorCodecTest extends CodecTestBase> { private static final Float[] VECTOR_ARGS = {1.0f, 2.5f}; @@ -45,16 +56,100 @@ public VectorCodecTest() { this.codec = TypeCodecs.vectorOf(vectorType, TypeCodecs.FLOAT); } + @DataProvider + public static Object[][] dataProvider() { + HashMap map1 = new HashMap<>(); + map1.put(1, "a"); + HashMap map2 = new HashMap<>(); + map2.put(2, "b"); + // For every row, data type, array of 2 values, formatted string, encoded bytes + return new Object[][] { + { + DataTypes.FLOAT, + new Float[] {1.0f, 2.5f}, + "[1.0, 2.5]", + Bytes.fromHexString("0x3f80000040200000") + }, + { + DataTypes.ASCII, + new String[] {"ab", "cde"}, + "['ab', 'cde']", + Bytes.fromHexString("0x02616203636465") + }, + { + DataTypes.BIGINT, + new Long[] {1L, 2L}, + "[1, 2]", + Bytes.fromHexString("0x00000000000000010000000000000002") + }, + { + DataTypes.BLOB, + new ByteBuffer[] {Bytes.fromHexString("0xCAFE"), Bytes.fromHexString("0xABCD")}, + "[0xcafe, 0xabcd]", + Bytes.fromHexString("0x02cafe02abcd") + }, + { + DataTypes.BOOLEAN, + new Boolean[] {true, false}, + "[true, false]", + Bytes.fromHexString("0x0100") + }, + { + DataTypes.TIME, + new LocalTime[] {LocalTime.ofNanoOfDay(1), LocalTime.ofNanoOfDay(2)}, + "['00:00:00.000000001', '00:00:00.000000002']", + Bytes.fromHexString("0x080000000000000001080000000000000002") + }, + { + DataTypes.mapOf(DataTypes.INT, DataTypes.ASCII), + new HashMap[] {map1, map2}, + "[{1:'a'}, {2:'b'}]", + Bytes.fromHexString( + "0x110000000100000004000000010000000161110000000100000004000000020000000162") + }, + { + DataTypes.vectorOf(DataTypes.INT, 1), + new CqlVector[] {CqlVector.newInstance(1), CqlVector.newInstance(2)}, + "[[1], [2]]", + Bytes.fromHexString("0x0000000100000002") + }, + { + DataTypes.vectorOf(DataTypes.TEXT, 1), + new CqlVector[] {CqlVector.newInstance("ab"), CqlVector.newInstance("cdef")}, + "[['ab'], ['cdef']]", + Bytes.fromHexString("0x03026162050463646566") + }, + { + DataTypes.vectorOf(DataTypes.vectorOf(DataTypes.FLOAT, 2), 1), + new CqlVector[] { + CqlVector.newInstance(CqlVector.newInstance(1.0f, 2.5f)), + CqlVector.newInstance(CqlVector.newInstance(3.0f, 4.5f)) + }, + "[[[1.0, 2.5]], [[3.0, 4.5]]]", + Bytes.fromHexString("0x3f800000402000004040000040900000") + }, + }; + } + + @UseDataProvider("dataProvider") @Test - public void should_encode() { - assertThat(encode(VECTOR)).isEqualTo(VECTOR_HEX_STRING); - assertThat(encode(null)).isNull(); + public void should_encode( + DataType dataType, Object[] values, String formatted, ByteBuffer bytes) { + TypeCodec> codec = getCodec(dataType); + CqlVector vector = CqlVector.newInstance(values); + assertThat(codec.encode(vector, ProtocolVersion.DEFAULT)).isEqualTo(bytes); + + // assertThat(encode(null)).isNull(); } - /** Too few eleements will cause an exception, extra elements will be silently ignored */ + /** Too few elements will cause an exception, extra elements will be silently ignored */ @Test - public void should_throw_on_encode_with_too_few_elements() { - assertThatThrownBy(() -> encode(VECTOR.subVector(0, 1))) + @UseDataProvider("dataProvider") + public void should_throw_on_encode_with_too_few_elements( + DataType dataType, Object[] values, String formatted, ByteBuffer bytes) { + TypeCodec> codec = getCodec(dataType); + assertThatThrownBy( + () -> codec.encode(CqlVector.newInstance(values[0]), ProtocolVersion.DEFAULT)) .isInstanceOf(IllegalArgumentException.class); } @@ -65,67 +160,96 @@ public void should_throw_on_encode_with_empty_list() { } @Test - public void should_encode_with_too_many_elements() { - Float[] doubledVectorContents = Arrays.copyOf(VECTOR_ARGS, VECTOR_ARGS.length * 2); - System.arraycopy(VECTOR_ARGS, 0, doubledVectorContents, VECTOR_ARGS.length, VECTOR_ARGS.length); - assertThat(encode(CqlVector.newInstance(doubledVectorContents))).isEqualTo(VECTOR_HEX_STRING); + @UseDataProvider("dataProvider") + public void should_throw_on_encode_with_too_many_elements( + DataType dataType, Object[] values, String formatted, ByteBuffer bytes) { + Object[] doubled = ArrayUtils.addAll(values, values); + TypeCodec> codec = getCodec(dataType); + assertThatThrownBy(() -> codec.encode(CqlVector.newInstance(doubled), ProtocolVersion.DEFAULT)) + .isInstanceOf(IllegalArgumentException.class); } @Test - public void should_decode() { - assertThat(decode(VECTOR_HEX_STRING)).isEqualTo(VECTOR); - assertThat(decode("0x")).isNull(); - assertThat(decode(null)).isNull(); + @UseDataProvider("dataProvider") + public void should_decode( + DataType dataType, Object[] values, String formatted, ByteBuffer bytes) { + TypeCodec> codec = getCodec(dataType); + assertThat(codec.decode(bytes, ProtocolVersion.DEFAULT)) + .isEqualTo(CqlVector.newInstance(values)); + // assertThat(decode("0x")).isNull(); + // assertThat(decode(null)).isNull(); } @Test - public void should_throw_on_decode_if_too_few_bytes() { - // Dropping 4 bytes would knock off exactly 1 float, anything less than that would be something - // we couldn't parse a float out of - for (int i = 1; i <= 3; ++i) { - // 2 chars of hex encoded string = 1 byte - int lastIndex = VECTOR_HEX_STRING.length() - (2 * i); - assertThatThrownBy(() -> decode(VECTOR_HEX_STRING.substring(0, lastIndex))) - .isInstanceOf(IllegalArgumentException.class); - } + @UseDataProvider("dataProvider") + public void should_throw_on_decode_if_too_few_bytes( + DataType dataType, Object[] values, String formatted, ByteBuffer bytes) { + TypeCodec> codec = getCodec(dataType); + int lastIndex = bytes.remaining() - 1; + assertThatThrownBy( + () -> + codec.decode( + (ByteBuffer) bytes.duplicate().limit(lastIndex), ProtocolVersion.DEFAULT)) + .isInstanceOf(IllegalArgumentException.class); } @Test - public void should_format() { - assertThat(format(VECTOR)).isEqualTo(FORMATTED_VECTOR); - assertThat(format(null)).isEqualTo("NULL"); + @UseDataProvider("dataProvider") + public void should_throw_on_decode_if_too_many_bytes( + DataType dataType, Object[] values, String formatted, ByteBuffer bytes) { + ByteBuffer doubled = ByteBuffer.allocate(bytes.remaining() * 2); + doubled.put(bytes.duplicate()).put(bytes.duplicate()).flip(); + TypeCodec> codec = getCodec(dataType); + assertThatThrownBy(() -> codec.decode(doubled, ProtocolVersion.DEFAULT)) + .isInstanceOf(IllegalArgumentException.class); } @Test - public void should_parse() { - assertThat(parse(FORMATTED_VECTOR)).isEqualTo(VECTOR); - assertThat(parse("NULL")).isNull(); - assertThat(parse("null")).isNull(); - assertThat(parse("")).isNull(); - assertThat(parse(null)).isNull(); + @UseDataProvider("dataProvider") + public void should_format( + DataType dataType, Object[] values, String formatted, ByteBuffer bytes) { + TypeCodec> codec = getCodec(dataType); + CqlVector vector = CqlVector.newInstance(values); + assertThat(codec.format(vector)).isEqualTo(formatted); + // assertThat(format(null)).isEqualTo("NULL"); } @Test - public void should_accept_data_type() { - assertThat(codec.accepts(new DefaultVectorType(DataTypes.FLOAT, 2))).isTrue(); - assertThat(codec.accepts(DataTypes.INT)).isFalse(); + @UseDataProvider("dataProvider") + public void should_parse(DataType dataType, Object[] values, String formatted, ByteBuffer bytes) { + TypeCodec> codec = getCodec(dataType); + assertThat(codec.parse(formatted)).isEqualTo(CqlVector.newInstance(values)); + // assertThat(parse("NULL")).isNull(); + // assertThat(parse("null")).isNull(); + // assertThat(parse("")).isNull(); + // assertThat(parse(null)).isNull(); } @Test - public void should_accept_vector_type_correct_dimension_only() { - assertThat(codec.accepts(new DefaultVectorType(DataTypes.FLOAT, 0))).isFalse(); - assertThat(codec.accepts(new DefaultVectorType(DataTypes.FLOAT, 1))).isFalse(); - assertThat(codec.accepts(new DefaultVectorType(DataTypes.FLOAT, 2))).isTrue(); - for (int i = 3; i < 1000; ++i) { - assertThat(codec.accepts(new DefaultVectorType(DataTypes.FLOAT, i))).isFalse(); - } + @UseDataProvider("dataProvider") + public void should_accept_data_type( + DataType dataType, Object[] values, String formatted, ByteBuffer bytes) { + TypeCodec> codec = getCodec(dataType); + assertThat(codec.accepts(new DefaultVectorType(dataType, 2))).isTrue(); + assertThat(codec.accepts(new DefaultVectorType(DataTypes.custom("non-existent"), 2))).isFalse(); } @Test - public void should_accept_generic_type() { - assertThat(codec.accepts(GenericType.vectorOf(GenericType.FLOAT))).isTrue(); - assertThat(codec.accepts(GenericType.vectorOf(GenericType.INTEGER))).isFalse(); - assertThat(codec.accepts(GenericType.of(Integer.class))).isFalse(); + @UseDataProvider("dataProvider") + public void should_accept_vector_type_correct_dimension_only( + DataType dataType, Object[] values, String formatted, ByteBuffer bytes) { + TypeCodec> codec = getCodec(dataType); + assertThat(codec.accepts(new DefaultVectorType(dataType, 0))).isFalse(); + assertThat(codec.accepts(new DefaultVectorType(dataType, 1))).isFalse(); + assertThat(codec.accepts(new DefaultVectorType(dataType, 3))).isFalse(); + } + + @Test + @UseDataProvider("dataProvider") + public void should_accept_generic_type( + DataType dataType, Object[] values, String formatted, ByteBuffer bytes) { + TypeCodec> codec = getCodec(dataType); + assertThat(codec.accepts(codec.getJavaType())).isTrue(); } @Test @@ -139,4 +263,9 @@ public void should_accept_object() { assertThat(codec.accepts(VECTOR)).isTrue(); assertThat(codec.accepts(Integer.MIN_VALUE)).isFalse(); } + + private static TypeCodec> getCodec(DataType dataType) { + return TypeCodecs.vectorOf( + DataTypes.vectorOf(dataType, 2), CodecRegistry.DEFAULT.codecFor(dataType)); + } } diff --git a/core/src/test/java/com/datastax/oss/driver/internal/core/type/codec/registry/CachingCodecRegistryTestDataProviders.java b/core/src/test/java/com/datastax/oss/driver/internal/core/type/codec/registry/CachingCodecRegistryTestDataProviders.java index cc867de0c35..4c0298bafad 100644 --- a/core/src/test/java/com/datastax/oss/driver/internal/core/type/codec/registry/CachingCodecRegistryTestDataProviders.java +++ b/core/src/test/java/com/datastax/oss/driver/internal/core/type/codec/registry/CachingCodecRegistryTestDataProviders.java @@ -337,11 +337,26 @@ public static Object[][] collectionsWithCqlAndJavaTypes() GenericType.vectorOf(BigInteger.class), CqlVector.newInstance(BigInteger.ONE) }, -// // vector with arbitrary types -// { -// DataTypes.vectorOf(DataTypes.listOf(DataTypes.INT), 1), -// -// } + // vector with arbitrary types + { + DataTypes.vectorOf(DataTypes.TEXT, 2), + GenericType.vectorOf(String.class), + GenericType.vectorOf(String.class), + CqlVector.newInstance("abc", "de") + }, + { + DataTypes.vectorOf(DataTypes.TIME, 2), + GenericType.vectorOf(LocalTime.class), + GenericType.vectorOf(LocalTime.class), + CqlVector.newInstance(LocalTime.MIDNIGHT, LocalTime.NOON) + }, + { + DataTypes.vectorOf(DataTypes.vectorOf(DataTypes.TINYINT, 2), 2), + GenericType.vectorOf(GenericType.vectorOf(Byte.class)), + GenericType.vectorOf(GenericType.vectorOf(Byte.class)), + CqlVector.newInstance( + CqlVector.newInstance((byte) 1, (byte) 2), CqlVector.newInstance((byte) 3, (byte) 4)) + }, }; } diff --git a/integration-tests/src/test/java/com/datastax/oss/driver/core/data/DataTypeIT.java b/integration-tests/src/test/java/com/datastax/oss/driver/core/data/DataTypeIT.java index 95bdface17d..e3d891454de 100644 --- a/integration-tests/src/test/java/com/datastax/oss/driver/core/data/DataTypeIT.java +++ b/integration-tests/src/test/java/com/datastax/oss/driver/core/data/DataTypeIT.java @@ -18,7 +18,6 @@ package com.datastax.oss.driver.core.data; import static org.assertj.core.api.Assertions.assertThat; -import static org.assertj.core.api.InstanceOfAssertFactories.type; import static org.junit.Assert.fail; import com.datastax.oss.driver.api.core.CqlIdentifier; @@ -47,7 +46,6 @@ import com.datastax.oss.driver.api.core.type.TupleType; import com.datastax.oss.driver.api.core.type.UserDefinedType; import com.datastax.oss.driver.api.core.type.codec.TypeCodec; -import com.datastax.oss.driver.api.core.type.reflect.GenericType; import com.datastax.oss.driver.api.testinfra.ccm.CcmRule; import com.datastax.oss.driver.api.testinfra.session.SessionRule; import com.datastax.oss.driver.categories.ParallelizableTests; @@ -267,39 +265,35 @@ public static Object[][] typeSamples() { UdtValue udtValue2 = udt.newValue(1, o[1]); samples.add(new Object[] {udt, udtValue2}); - if (CCM_RULE.getCassandraVersion().compareTo(Version.parse("5.0")) >= 0){ + if (CCM_RULE.getCassandraVersion().compareTo(Version.parse("5.0")) >= 0) { // vector of type CqlVector vector = CqlVector.newInstance(o[1]); samples.add(new Object[] {DataTypes.vectorOf(dataType, 1), vector}); } - if (o[1].equals("ascii")){ - // once - CqlVector vector = CqlVector.newInstance(CqlVector.newInstance(1, 2)); - samples.add(new Object[] {DataTypes.vectorOf(DataTypes.vectorOf(DataTypes.INT, 2), 1), vector}); - } return samples.stream(); }) .toArray(Object[][]::new); } @DataProvider - public static Object[][] addVectors(){ + public static Object[][] addVectors() { Object[][] previousSamples = typeSamples(); if (CCM_RULE.getCassandraVersion().compareTo(Version.parse("5.0")) < 0) return previousSamples; - return Arrays.stream(previousSamples).flatMap( - o -> { - List samples = new ArrayList<>(); - samples.add(o); - if (o[1] == null) return samples.stream(); - DataType dataType = (DataType) o[0]; - CqlVector vector = CqlVector.newInstance(o[1]); - samples.add(new Object[] {DataTypes.vectorOf(dataType, 1), vector}); - return samples.stream(); - }).toArray(Object[][]::new); + return Arrays.stream(previousSamples) + .flatMap( + o -> { + List samples = new ArrayList<>(); + samples.add(o); + if (o[1] == null) return samples.stream(); + DataType dataType = (DataType) o[0]; + CqlVector vector = CqlVector.newInstance(o[1]); + samples.add(new Object[] {DataTypes.vectorOf(dataType, 1), vector}); + return samples.stream(); + }) + .toArray(Object[][]::new); } - @BeforeClass public static void createTable() { // Create a table with all types being tested with. From 14e908d8adf63a6507f63838b4358839ce4781d1 Mon Sep 17 00:00:00 2001 From: janehe Date: Fri, 30 Aug 2024 06:10:02 -0800 Subject: [PATCH 18/24] more tests and try to fix toString --- .../oss/driver/api/core/data/CqlVector.java | 5 +- .../internal/core/type/codec/VectorCodec.java | 1 - .../driver/api/core/data/CqlVectorTest.java | 152 ++++++++++-------- .../core/type/codec/VectorCodecTest.java | 56 +++---- 4 files changed, 111 insertions(+), 103 deletions(-) diff --git a/core/src/main/java/com/datastax/oss/driver/api/core/data/CqlVector.java b/core/src/main/java/com/datastax/oss/driver/api/core/data/CqlVector.java index 2014119444e..f8892f6b9ca 100644 --- a/core/src/main/java/com/datastax/oss/driver/api/core/data/CqlVector.java +++ b/core/src/main/java/com/datastax/oss/driver/api/core/data/CqlVector.java @@ -18,6 +18,7 @@ package com.datastax.oss.driver.api.core.data; import com.datastax.oss.driver.api.core.type.codec.TypeCodec; +import com.datastax.oss.driver.api.core.type.codec.registry.CodecRegistry; import com.datastax.oss.driver.internal.core.type.codec.ParseUtils; import com.datastax.oss.driver.shaded.guava.common.base.Preconditions; import com.datastax.oss.driver.shaded.guava.common.base.Predicates; @@ -34,6 +35,7 @@ import java.util.Iterator; import java.util.List; import java.util.Objects; +import java.util.stream.Collectors; import java.util.stream.Stream; /** @@ -230,7 +232,8 @@ public int hashCode() { @Override public String toString() { - return Iterables.toString(this.list); + TypeCodec subcodec = CodecRegistry.DEFAULT.codecFor(list.get(0)); + return this.list.stream().map(subcodec::format).collect(Collectors.joining(", ", "[", "]")); } /** diff --git a/core/src/main/java/com/datastax/oss/driver/internal/core/type/codec/VectorCodec.java b/core/src/main/java/com/datastax/oss/driver/internal/core/type/codec/VectorCodec.java index 6a97eb1eaac..3de08087774 100644 --- a/core/src/main/java/com/datastax/oss/driver/internal/core/type/codec/VectorCodec.java +++ b/core/src/main/java/com/datastax/oss/driver/internal/core/type/codec/VectorCodec.java @@ -105,7 +105,6 @@ public CqlVector decode( @Override public String format(CqlVector value) { if (value == null) return "NULL"; - return value.stream().map(subtypeCodec::format).collect(Collectors.joining(", ", "[", "]")); } diff --git a/core/src/test/java/com/datastax/oss/driver/api/core/data/CqlVectorTest.java b/core/src/test/java/com/datastax/oss/driver/api/core/data/CqlVectorTest.java index 90f4cc6e776..2f5b505daa2 100644 --- a/core/src/test/java/com/datastax/oss/driver/api/core/data/CqlVectorTest.java +++ b/core/src/test/java/com/datastax/oss/driver/api/core/data/CqlVectorTest.java @@ -21,58 +21,77 @@ import static org.assertj.core.api.Assertions.assertThatThrownBy; import static org.assertj.core.api.Assertions.fail; +import com.datastax.oss.driver.api.core.type.codec.TypeCodec; import com.datastax.oss.driver.api.core.type.codec.TypeCodecs; +import com.datastax.oss.driver.api.core.type.codec.registry.CodecRegistry; import com.datastax.oss.driver.internal.SerializationHelper; import com.datastax.oss.driver.shaded.guava.common.collect.Iterators; import java.io.ByteArrayInputStream; import java.io.ObjectInputStream; import java.io.ObjectStreamException; +import java.time.LocalTime; import java.util.AbstractList; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; +import java.util.Iterator; import java.util.List; import java.util.stream.Collectors; + +import com.tngtech.java.junit.dataprovider.DataProvider; +import com.tngtech.java.junit.dataprovider.DataProviderRunner; +import com.tngtech.java.junit.dataprovider.UseDataProvider; import org.apache.commons.codec.DecoderException; import org.apache.commons.codec.binary.Hex; import org.assertj.core.util.Lists; import org.junit.Test; +import org.junit.runner.RunWith; +@RunWith(DataProviderRunner.class) public class CqlVectorTest { private static final Float[] VECTOR_ARGS = {1.0f, 2.5f}; - private void validate_built_vector(CqlVector vec) { + @DataProvider + public static Object[][] dataProvider() { + return new Object[][]{ + {new Float[]{1.0f, 2.5f}}, + {new LocalTime[]{LocalTime.of(1, 2), LocalTime.of(3, 4)}}, + {new List[]{Arrays.asList(1, 2), Arrays.asList(3, 4)}}, + {new CqlVector[]{CqlVector.newInstance("a", "bc"), CqlVector.newInstance("d", "ef")}} + }; + } + private void validate_built_vector(CqlVector vec, Object[] expectedVals) { assertThat(vec.size()).isEqualTo(2); assertThat(vec.isEmpty()).isFalse(); - assertThat(vec.get(0)).isEqualTo(VECTOR_ARGS[0]); - assertThat(vec.get(1)).isEqualTo(VECTOR_ARGS[1]); + assertThat(vec.get(0)).isEqualTo(expectedVals[0]); + assertThat(vec.get(1)).isEqualTo(expectedVals[1]); } + @UseDataProvider("dataProvider") @Test - public void should_build_vector_from_elements() { - - validate_built_vector(CqlVector.newInstance(VECTOR_ARGS)); + public void should_build_vector_from_elements(Object[] vals) { + validate_built_vector(CqlVector.newInstance(vals), vals); } @Test - public void should_build_vector_from_list() { - - validate_built_vector(CqlVector.newInstance(Lists.newArrayList(VECTOR_ARGS))); + @UseDataProvider("dataProvider") + public void should_build_vector_from_list(Object[] vals) { + validate_built_vector(CqlVector.newInstance(Lists.newArrayList(vals)), vals); } @Test - public void should_build_vector_from_tostring_output() { - - CqlVector vector1 = CqlVector.newInstance(VECTOR_ARGS); - CqlVector vector2 = CqlVector.from(vector1.toString(), TypeCodecs.FLOAT); + @UseDataProvider("dataProvider") + public void should_build_vector_from_tostring_output(Object[] vals) { + CqlVector vector1 = CqlVector.newInstance(vals); + TypeCodec codec = CodecRegistry.DEFAULT.codecFor(vals[0]); + CqlVector vector2 = CqlVector.from(vector1.toString(), codec); assertThat(vector2).isEqualTo(vector1); } @Test public void should_throw_from_null_string() { - assertThatThrownBy( () -> { CqlVector.from(null, TypeCodecs.FLOAT); @@ -123,94 +142,89 @@ public void should_build_empty_vector() { } @Test - public void should_behave_mostly_like_a_list() { - - CqlVector vector = CqlVector.newInstance(VECTOR_ARGS); - assertThat(vector.get(0)).isEqualTo(VECTOR_ARGS[0]); - Float newVal = VECTOR_ARGS[0] * 2; - vector.set(0, newVal); - assertThat(vector.get(0)).isEqualTo(newVal); + @UseDataProvider("dataProvider") + public void should_behave_mostly_like_a_list(T[] vals) { + CqlVector vector = CqlVector.newInstance(vals); + assertThat(vector.get(0)).isEqualTo(vals[0]); + vector.set(0, vals[1]); + assertThat(vector.get(0)).isEqualTo(vals[1]); assertThat(vector.isEmpty()).isFalse(); assertThat(vector.size()).isEqualTo(2); - assertThat(Iterators.toArray(vector.iterator(), Float.class)).isEqualTo(VECTOR_ARGS); + Iterator iterator = vector.iterator(); + assertThat(iterator.next()).isEqualTo(vals[1]); + assertThat(iterator.next()).isEqualTo(vals[1]); } @Test - public void should_play_nicely_with_streams() { - - CqlVector vector = CqlVector.newInstance(VECTOR_ARGS); - List results = + @UseDataProvider("dataProvider") + public void should_play_nicely_with_streams(T[] vals) { + CqlVector vector = CqlVector.newInstance(vals); + List results = vector.stream() - .map((f) -> f * 2) - .collect(Collectors.toCollection(() -> new ArrayList())); + .map(Object::toString) + .collect(Collectors.toCollection(() -> new ArrayList())); for (int i = 0; i < vector.size(); ++i) { - assertThat(results.get(i)).isEqualTo(vector.get(i) * 2); + assertThat(results.get(i)).isEqualTo(vector.get(i).toString()); } } @Test - public void should_reflect_changes_to_mutable_list() { - - List theList = Lists.newArrayList(1.1f, 2.2f, 3.3f); - CqlVector vector = CqlVector.newInstance(theList); - assertThat(vector.size()).isEqualTo(3); - assertThat(vector.get(2)).isEqualTo(3.3f); - - float newVal1 = 4.4f; - theList.set(2, newVal1); - assertThat(vector.size()).isEqualTo(3); - assertThat(vector.get(2)).isEqualTo(newVal1); - - float newVal2 = 5.5f; - theList.add(newVal2); - assertThat(vector.size()).isEqualTo(4); - assertThat(vector.get(3)).isEqualTo(newVal2); + @UseDataProvider("dataProvider") + public void should_reflect_changes_to_mutable_list(T[] vals) { + List theList = Lists.newArrayList(vals); + CqlVector vector = CqlVector.newInstance(theList); + assertThat(vector.size()).isEqualTo(2); + assertThat(vector.get(1)).isEqualTo(vals[1]); + + T newVal = vals[0]; + theList.set(1, newVal); + assertThat(vector.size()).isEqualTo(2); + assertThat(vector.get(1)).isEqualTo(newVal); } @Test - public void should_reflect_changes_to_array() { - - Float[] theArray = new Float[] {1.1f, 2.2f, 3.3f}; - CqlVector vector = CqlVector.newInstance(theArray); - assertThat(vector.size()).isEqualTo(3); - assertThat(vector.get(2)).isEqualTo(3.3f); + @UseDataProvider("dataProvider") + public void should_reflect_changes_to_array(T[] theArray) { + CqlVector vector = CqlVector.newInstance(theArray); + assertThat(vector.size()).isEqualTo(2); + assertThat(vector.get(1)).isEqualTo(theArray[1]); - float newVal1 = 4.4f; - theArray[2] = newVal1; - assertThat(vector.size()).isEqualTo(3); - assertThat(vector.get(2)).isEqualTo(newVal1); + T newVal = theArray[0]; + theArray[1] = newVal; + assertThat(vector.size()).isEqualTo(2); + assertThat(vector.get(1)).isEqualTo(newVal); } @Test - public void should_correctly_compare_vectors() { - - Float[] args = VECTOR_ARGS.clone(); - CqlVector vector1 = CqlVector.newInstance(args); - CqlVector vector2 = CqlVector.newInstance(args); - CqlVector vector3 = CqlVector.newInstance(Lists.newArrayList(args)); + @UseDataProvider("dataProvider") + public void should_correctly_compare_vectors(T[] vals) { + CqlVector vector1 = CqlVector.newInstance(vals); + CqlVector vector2 = CqlVector.newInstance(vals); + CqlVector vector3 = CqlVector.newInstance(Lists.newArrayList(vals)); assertThat(vector1).isNotSameAs(vector2); assertThat(vector1).isEqualTo(vector2); assertThat(vector1).isNotSameAs(vector3); assertThat(vector1).isEqualTo(vector3); - Float[] differentArgs = args.clone(); - float newVal = differentArgs[0] * 2; + T[] differentArgs = Arrays.copyOf(vals, vals.length); + T newVal = differentArgs[1]; differentArgs[0] = newVal; - CqlVector vector4 = CqlVector.newInstance(differentArgs); + CqlVector vector4 = CqlVector.newInstance(differentArgs); assertThat(vector1).isNotSameAs(vector4); assertThat(vector1).isNotEqualTo(vector4); - Float[] biggerArgs = Arrays.copyOf(args, args.length + 1); + T[] biggerArgs = Arrays.copyOf(vals, vals.length + 1); biggerArgs[biggerArgs.length - 1] = newVal; - CqlVector vector5 = CqlVector.newInstance(biggerArgs); + CqlVector vector5 = CqlVector.newInstance(biggerArgs); assertThat(vector1).isNotSameAs(vector5); assertThat(vector1).isNotEqualTo(vector5); } @Test - public void should_serialize_and_deserialize() throws Exception { - CqlVector initial = CqlVector.newInstance(VECTOR_ARGS); - CqlVector deserialized = SerializationHelper.serializeAndDeserialize(initial); + @UseDataProvider("dataProvider") + public void should_serialize_and_deserialize(T[] vals) throws Exception { + CqlVector initial = CqlVector.newInstance(vals); + CqlVector deserialized = SerializationHelper.serializeAndDeserialize(initial); assertThat(deserialized).isEqualTo(initial); } diff --git a/core/src/test/java/com/datastax/oss/driver/internal/core/type/codec/VectorCodecTest.java b/core/src/test/java/com/datastax/oss/driver/internal/core/type/codec/VectorCodecTest.java index 2b77152c97a..548e497fed5 100644 --- a/core/src/test/java/com/datastax/oss/driver/internal/core/type/codec/VectorCodecTest.java +++ b/core/src/test/java/com/datastax/oss/driver/internal/core/type/codec/VectorCodecTest.java @@ -33,6 +33,8 @@ import com.tngtech.java.junit.dataprovider.DataProvider; import com.tngtech.java.junit.dataprovider.DataProviderRunner; import com.tngtech.java.junit.dataprovider.UseDataProvider; + +import java.nio.Buffer; import java.nio.ByteBuffer; import java.time.LocalTime; import java.util.HashMap; @@ -41,20 +43,7 @@ import org.junit.runner.RunWith; @RunWith(DataProviderRunner.class) -public class VectorCodecTest extends CodecTestBase> { - - private static final Float[] VECTOR_ARGS = {1.0f, 2.5f}; - - private static final CqlVector VECTOR = CqlVector.newInstance(VECTOR_ARGS); - - private static final String VECTOR_HEX_STRING = "0x" + "3f800000" + "40200000"; - - private static final String FORMATTED_VECTOR = "[1.0, 2.5]"; - - public VectorCodecTest() { - VectorType vectorType = DataTypes.vectorOf(DataTypes.FLOAT, 2); - this.codec = TypeCodecs.vectorOf(vectorType, TypeCodecs.FLOAT); - } +public class VectorCodecTest { @DataProvider public static Object[][] dataProvider() { @@ -138,8 +127,6 @@ public void should_encode( TypeCodec> codec = getCodec(dataType); CqlVector vector = CqlVector.newInstance(values); assertThat(codec.encode(vector, ProtocolVersion.DEFAULT)).isEqualTo(bytes); - - // assertThat(encode(null)).isNull(); } /** Too few elements will cause an exception, extra elements will be silently ignored */ @@ -153,12 +140,6 @@ public void should_throw_on_encode_with_too_few_elements( .isInstanceOf(IllegalArgumentException.class); } - @Test - public void should_throw_on_encode_with_empty_list() { - assertThatThrownBy(() -> encode(CqlVector.newInstance())) - .isInstanceOf(IllegalArgumentException.class); - } - @Test @UseDataProvider("dataProvider") public void should_throw_on_encode_with_too_many_elements( @@ -176,8 +157,6 @@ public void should_decode( TypeCodec> codec = getCodec(dataType); assertThat(codec.decode(bytes, ProtocolVersion.DEFAULT)) .isEqualTo(CqlVector.newInstance(values)); - // assertThat(decode("0x")).isNull(); - // assertThat(decode(null)).isNull(); } @Test @@ -211,7 +190,6 @@ public void should_format( TypeCodec> codec = getCodec(dataType); CqlVector vector = CqlVector.newInstance(values); assertThat(codec.format(vector)).isEqualTo(formatted); - // assertThat(format(null)).isEqualTo("NULL"); } @Test @@ -219,10 +197,6 @@ public void should_format( public void should_parse(DataType dataType, Object[] values, String formatted, ByteBuffer bytes) { TypeCodec> codec = getCodec(dataType); assertThat(codec.parse(formatted)).isEqualTo(CqlVector.newInstance(values)); - // assertThat(parse("NULL")).isNull(); - // assertThat(parse("null")).isNull(); - // assertThat(parse("")).isNull(); - // assertThat(parse(null)).isNull(); } @Test @@ -253,17 +227,35 @@ public void should_accept_generic_type( } @Test - public void should_accept_raw_type() { + @UseDataProvider("dataProvider") + public void should_accept_raw_type(DataType dataType, Object[] values, String formatted, ByteBuffer bytes) { + TypeCodec> codec = getCodec(dataType); assertThat(codec.accepts(CqlVector.class)).isTrue(); assertThat(codec.accepts(Integer.class)).isFalse(); } @Test - public void should_accept_object() { - assertThat(codec.accepts(VECTOR)).isTrue(); + @UseDataProvider("dataProvider") + public void should_accept_object(DataType dataType, Object[] values, String formatted, ByteBuffer bytes) { + TypeCodec> codec = getCodec(dataType); + CqlVector vector = CqlVector.newInstance(values); + assertThat(codec.accepts(vector)).isTrue(); assertThat(codec.accepts(Integer.MIN_VALUE)).isFalse(); } + @Test + public void should_handle_null_and_empty() { + TypeCodec> codec = getCodec(DataTypes.FLOAT); + assertThat(codec.encode(null, ProtocolVersion.DEFAULT)).isNull(); + assertThat(codec.decode(Bytes.fromHexString("0x"), ProtocolVersion.DEFAULT)).isNull(); + assertThat(codec.format(null)).isEqualTo("NULL"); + assertThat(codec.parse("NULL")).isNull(); + assertThat(codec.parse("null")).isNull(); + assertThat(codec.parse("")).isNull(); + assertThat(codec.parse(null)).isNull(); + assertThatThrownBy(() -> codec.encode(CqlVector.newInstance(), ProtocolVersion.DEFAULT)) + .isInstanceOf(IllegalArgumentException.class); + } private static TypeCodec> getCodec(DataType dataType) { return TypeCodecs.vectorOf( DataTypes.vectorOf(dataType, 2), CodecRegistry.DEFAULT.codecFor(dataType)); From 5834c25cdb404aa313818337ee0a0a3360960244 Mon Sep 17 00:00:00 2001 From: janehe Date: Tue, 3 Sep 2024 13:57:36 -0800 Subject: [PATCH 19/24] fmt --- .../oss/driver/api/core/data/CqlVector.java | 9 +++++---- .../driver/api/core/data/CqlVectorTest.java | 20 +++++++++---------- .../core/type/codec/VectorCodecTest.java | 14 ++++++------- 3 files changed, 21 insertions(+), 22 deletions(-) diff --git a/core/src/main/java/com/datastax/oss/driver/api/core/data/CqlVector.java b/core/src/main/java/com/datastax/oss/driver/api/core/data/CqlVector.java index f8892f6b9ca..e897dddb9de 100644 --- a/core/src/main/java/com/datastax/oss/driver/api/core/data/CqlVector.java +++ b/core/src/main/java/com/datastax/oss/driver/api/core/data/CqlVector.java @@ -96,7 +96,7 @@ public static CqlVector from(@NonNull String str, @NonNull TypeCodec s if (str.charAt(idx++) != '[') throw new IllegalArgumentException( String.format( - "Cannot parse list value from \"%s\", at character %d expecting '[' but got '%c'", + "Cannot parse vector value from \"%s\", at character %d expecting '[' but got '%c'", str, idx, str.charAt(idx))); idx = ParseUtils.skipSpaces(str, idx); @@ -113,7 +113,8 @@ public static CqlVector from(@NonNull String str, @NonNull TypeCodec s } catch (IllegalArgumentException e) { throw new IllegalArgumentException( String.format( - "Cannot parse list value from \"%s\", invalid CQL value at character %d", str, idx), + "Cannot parse vector value from \"%s\", invalid CQL value at character %d", + str, idx), e); } @@ -125,13 +126,13 @@ public static CqlVector from(@NonNull String str, @NonNull TypeCodec s if (str.charAt(idx++) != ',') throw new IllegalArgumentException( String.format( - "Cannot parse list value from \"%s\", at character %d expecting ',' but got '%c'", + "Cannot parse vector value from \"%s\", at character %d expecting ',' but got '%c'", str, idx, str.charAt(idx))); idx = ParseUtils.skipSpaces(str, idx); } throw new IllegalArgumentException( - String.format("Malformed list value \"%s\", missing closing ']'", str)); + String.format("Malformed vector value \"%s\", missing closing ']'", str)); } private final List list; diff --git a/core/src/test/java/com/datastax/oss/driver/api/core/data/CqlVectorTest.java b/core/src/test/java/com/datastax/oss/driver/api/core/data/CqlVectorTest.java index 2f5b505daa2..82290d545df 100644 --- a/core/src/test/java/com/datastax/oss/driver/api/core/data/CqlVectorTest.java +++ b/core/src/test/java/com/datastax/oss/driver/api/core/data/CqlVectorTest.java @@ -25,7 +25,9 @@ import com.datastax.oss.driver.api.core.type.codec.TypeCodecs; import com.datastax.oss.driver.api.core.type.codec.registry.CodecRegistry; import com.datastax.oss.driver.internal.SerializationHelper; -import com.datastax.oss.driver.shaded.guava.common.collect.Iterators; +import com.tngtech.java.junit.dataprovider.DataProvider; +import com.tngtech.java.junit.dataprovider.DataProviderRunner; +import com.tngtech.java.junit.dataprovider.UseDataProvider; import java.io.ByteArrayInputStream; import java.io.ObjectInputStream; import java.io.ObjectStreamException; @@ -37,10 +39,6 @@ import java.util.Iterator; import java.util.List; import java.util.stream.Collectors; - -import com.tngtech.java.junit.dataprovider.DataProvider; -import com.tngtech.java.junit.dataprovider.DataProviderRunner; -import com.tngtech.java.junit.dataprovider.UseDataProvider; import org.apache.commons.codec.DecoderException; import org.apache.commons.codec.binary.Hex; import org.assertj.core.util.Lists; @@ -54,11 +52,11 @@ public class CqlVectorTest { @DataProvider public static Object[][] dataProvider() { - return new Object[][]{ - {new Float[]{1.0f, 2.5f}}, - {new LocalTime[]{LocalTime.of(1, 2), LocalTime.of(3, 4)}}, - {new List[]{Arrays.asList(1, 2), Arrays.asList(3, 4)}}, - {new CqlVector[]{CqlVector.newInstance("a", "bc"), CqlVector.newInstance("d", "ef")}} + return new Object[][] { + {new Float[] {1.0f, 2.5f}}, + {new LocalTime[] {LocalTime.of(1, 2), LocalTime.of(3, 4)}}, + {new List[] {Arrays.asList(1, 2), Arrays.asList(3, 4)}}, + {new CqlVector[] {CqlVector.newInstance("a", "bc"), CqlVector.newInstance("d", "ef")}} }; } @@ -143,7 +141,7 @@ public void should_build_empty_vector() { @Test @UseDataProvider("dataProvider") - public void should_behave_mostly_like_a_list(T[] vals) { + public void should_behave_mostly_like_a_list(T[] vals) { CqlVector vector = CqlVector.newInstance(vals); assertThat(vector.get(0)).isEqualTo(vals[0]); vector.set(0, vals[1]); diff --git a/core/src/test/java/com/datastax/oss/driver/internal/core/type/codec/VectorCodecTest.java b/core/src/test/java/com/datastax/oss/driver/internal/core/type/codec/VectorCodecTest.java index 548e497fed5..c92ca5dc99c 100644 --- a/core/src/test/java/com/datastax/oss/driver/internal/core/type/codec/VectorCodecTest.java +++ b/core/src/test/java/com/datastax/oss/driver/internal/core/type/codec/VectorCodecTest.java @@ -24,7 +24,6 @@ import com.datastax.oss.driver.api.core.data.CqlVector; import com.datastax.oss.driver.api.core.type.DataType; import com.datastax.oss.driver.api.core.type.DataTypes; -import com.datastax.oss.driver.api.core.type.VectorType; import com.datastax.oss.driver.api.core.type.codec.TypeCodec; import com.datastax.oss.driver.api.core.type.codec.TypeCodecs; import com.datastax.oss.driver.api.core.type.codec.registry.CodecRegistry; @@ -33,8 +32,6 @@ import com.tngtech.java.junit.dataprovider.DataProvider; import com.tngtech.java.junit.dataprovider.DataProviderRunner; import com.tngtech.java.junit.dataprovider.UseDataProvider; - -import java.nio.Buffer; import java.nio.ByteBuffer; import java.time.LocalTime; import java.util.HashMap; @@ -43,7 +40,7 @@ import org.junit.runner.RunWith; @RunWith(DataProviderRunner.class) -public class VectorCodecTest { +public class VectorCodecTest { @DataProvider public static Object[][] dataProvider() { @@ -228,7 +225,8 @@ public void should_accept_generic_type( @Test @UseDataProvider("dataProvider") - public void should_accept_raw_type(DataType dataType, Object[] values, String formatted, ByteBuffer bytes) { + public void should_accept_raw_type( + DataType dataType, Object[] values, String formatted, ByteBuffer bytes) { TypeCodec> codec = getCodec(dataType); assertThat(codec.accepts(CqlVector.class)).isTrue(); assertThat(codec.accepts(Integer.class)).isFalse(); @@ -236,7 +234,8 @@ public void should_accept_raw_type(DataType dataType, Object[] values, String fo @Test @UseDataProvider("dataProvider") - public void should_accept_object(DataType dataType, Object[] values, String formatted, ByteBuffer bytes) { + public void should_accept_object( + DataType dataType, Object[] values, String formatted, ByteBuffer bytes) { TypeCodec> codec = getCodec(dataType); CqlVector vector = CqlVector.newInstance(values); assertThat(codec.accepts(vector)).isTrue(); @@ -254,8 +253,9 @@ public void should_handle_null_and_empty() { assertThat(codec.parse("")).isNull(); assertThat(codec.parse(null)).isNull(); assertThatThrownBy(() -> codec.encode(CqlVector.newInstance(), ProtocolVersion.DEFAULT)) - .isInstanceOf(IllegalArgumentException.class); + .isInstanceOf(IllegalArgumentException.class); } + private static TypeCodec> getCodec(DataType dataType) { return TypeCodecs.vectorOf( DataTypes.vectorOf(dataType, 2), CodecRegistry.DEFAULT.codecFor(dataType)); From 680a6a01ef4268bcffd4c32d969811c7b9f28872 Mon Sep 17 00:00:00 2001 From: janehe Date: Tue, 3 Sep 2024 14:01:21 -0800 Subject: [PATCH 20/24] revert ccmbridge --- .../com/datastax/oss/driver/api/testinfra/ccm/CcmBridge.java | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/test-infra/src/main/java/com/datastax/oss/driver/api/testinfra/ccm/CcmBridge.java b/test-infra/src/main/java/com/datastax/oss/driver/api/testinfra/ccm/CcmBridge.java index 0628b0ac211..995513e3919 100644 --- a/test-infra/src/main/java/com/datastax/oss/driver/api/testinfra/ccm/CcmBridge.java +++ b/test-infra/src/main/java/com/datastax/oss/driver/api/testinfra/ccm/CcmBridge.java @@ -412,9 +412,7 @@ protected void processLine(String line, int logLevel) { executor.setStreamHandler(streamHandler); executor.setWatchdog(watchDog); - Map env = new LinkedHashMap<>(System.getenv()); - env.put("JAVA_HOME", "/opt/homebrew/Cellar/openjdk@11/11.0.21/libexec/openjdk.jdk/Contents/Home"); - int retValue = executor.execute(cli, env); + int retValue = executor.execute(cli); if (retValue != 0) { LOG.error("Non-zero exit code ({}) returned from executing ccm command: {}", retValue, cli); } From 86088d6d53ec0a0ac7aeb0c38ed4ff00cb6c0130 Mon Sep 17 00:00:00 2001 From: janehe Date: Tue, 3 Sep 2024 16:14:38 -0800 Subject: [PATCH 21/24] fmt --- .../java/com/datastax/oss/driver/api/core/data/CqlVector.java | 1 + .../java/com/datastax/oss/driver/api/core/type/DataTypes.java | 2 -- .../oss/driver/internal/core/type/codec/VectorCodec.java | 1 + 3 files changed, 2 insertions(+), 2 deletions(-) diff --git a/core/src/main/java/com/datastax/oss/driver/api/core/data/CqlVector.java b/core/src/main/java/com/datastax/oss/driver/api/core/data/CqlVector.java index e897dddb9de..ef42b266e10 100644 --- a/core/src/main/java/com/datastax/oss/driver/api/core/data/CqlVector.java +++ b/core/src/main/java/com/datastax/oss/driver/api/core/data/CqlVector.java @@ -233,6 +233,7 @@ public int hashCode() { @Override public String toString() { + if (this.list.isEmpty()) return "[]"; TypeCodec subcodec = CodecRegistry.DEFAULT.codecFor(list.get(0)); return this.list.stream().map(subcodec::format).collect(Collectors.joining(", ", "[", "]")); } diff --git a/core/src/main/java/com/datastax/oss/driver/api/core/type/DataTypes.java b/core/src/main/java/com/datastax/oss/driver/api/core/type/DataTypes.java index a08f68a8557..4447e283068 100644 --- a/core/src/main/java/com/datastax/oss/driver/api/core/type/DataTypes.java +++ b/core/src/main/java/com/datastax/oss/driver/api/core/type/DataTypes.java @@ -27,7 +27,6 @@ import com.datastax.oss.driver.internal.core.type.DefaultTupleType; import com.datastax.oss.driver.internal.core.type.DefaultVectorType; import com.datastax.oss.driver.internal.core.type.PrimitiveType; -import com.datastax.oss.driver.shaded.guava.common.base.Splitter; import com.datastax.oss.driver.shaded.guava.common.collect.ImmutableList; import com.datastax.oss.protocol.internal.ProtocolConstants; import edu.umd.cs.findbugs.annotations.NonNull; @@ -58,7 +57,6 @@ public class DataTypes { public static final DataType DURATION = new PrimitiveType(ProtocolConstants.DataType.DURATION); private static final DataTypeClassNameParser classNameParser = new DataTypeClassNameParser(); - private static final Splitter paramSplitter = Splitter.on(',').trimResults(); @NonNull public static DataType custom(@NonNull String className) { diff --git a/core/src/main/java/com/datastax/oss/driver/internal/core/type/codec/VectorCodec.java b/core/src/main/java/com/datastax/oss/driver/internal/core/type/codec/VectorCodec.java index 3de08087774..30451e894ad 100644 --- a/core/src/main/java/com/datastax/oss/driver/internal/core/type/codec/VectorCodec.java +++ b/core/src/main/java/com/datastax/oss/driver/internal/core/type/codec/VectorCodec.java @@ -65,6 +65,7 @@ public GenericType> getJavaType() { } @NonNull + @Override public Optional serializedSize() { return subtypeCodec.serializedSize().isPresent() ? Optional.of(subtypeCodec.serializedSize().get() * cqlType.getDimensions()) From 1c17c7232bbe80424d2437cb91b54501afa390c5 Mon Sep 17 00:00:00 2001 From: janehe Date: Wed, 4 Sep 2024 22:24:35 -0800 Subject: [PATCH 22/24] add revapi.json --- core/revapi.json | 297 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 297 insertions(+) diff --git a/core/revapi.json b/core/revapi.json index 318e29709ec..94a1862be99 100644 --- a/core/revapi.json +++ b/core/revapi.json @@ -6956,6 +6956,303 @@ "old": "method java.lang.Throwable java.lang.Throwable::fillInStackTrace() @ com.fasterxml.jackson.databind.deser.UnresolvedForwardReference", "new": "method com.fasterxml.jackson.databind.deser.UnresolvedForwardReference com.fasterxml.jackson.databind.deser.UnresolvedForwardReference::fillInStackTrace()", "justification": "Upgrade jackson-databind to 2.13.4.1 to address CVEs, API change cause: https://github.com/FasterXML/jackson-databind/issues/3419" + }, + { + "code": "java.method.parameterTypeParameterChanged", + "old": "parameter com.datastax.oss.driver.api.core.data.CqlVector com.datastax.oss.driver.api.core.data.CqlVector::from(java.lang.String, ===com.datastax.oss.driver.api.core.type.codec.TypeCodec===)", + "new": "parameter com.datastax.oss.driver.api.core.data.CqlVector com.datastax.oss.driver.api.core.data.CqlVector::from(java.lang.String, ===com.datastax.oss.driver.api.core.type.codec.TypeCodec===)", + "justification": "Extend driver vector support to arbitrary subtypes for JAVA-3143" + }, + { + "code": "java.method.returnTypeTypeParametersChanged", + "old": "method com.datastax.oss.driver.api.core.data.CqlVector com.datastax.oss.driver.api.core.data.CqlVector::from(java.lang.String, com.datastax.oss.driver.api.core.type.codec.TypeCodec)", + "new": "method com.datastax.oss.driver.api.core.data.CqlVector com.datastax.oss.driver.api.core.data.CqlVector::from(java.lang.String, com.datastax.oss.driver.api.core.type.codec.TypeCodec)", + "justification": "Extend driver vector support to arbitrary subtypes for JAVA-3143" + }, + { + "code": "java.generics.formalTypeParameterChanged", + "old": "method com.datastax.oss.driver.api.core.data.CqlVector com.datastax.oss.driver.api.core.data.CqlVector::from(java.lang.String, com.datastax.oss.driver.api.core.type.codec.TypeCodec)", + "new": "method com.datastax.oss.driver.api.core.data.CqlVector com.datastax.oss.driver.api.core.data.CqlVector::from(java.lang.String, com.datastax.oss.driver.api.core.type.codec.TypeCodec)", + "justification": "Extend driver vector support to arbitrary subtypes for JAVA-3143" + }, + { + "code": "java.method.returnTypeChanged", + "old": "method T com.datastax.oss.driver.api.core.data.CqlVector::get(int)", + "new": "method T com.datastax.oss.driver.api.core.data.CqlVector::get(int)", + "justification": "Extend driver vector support to arbitrary subtypes for JAVA-3143" + }, + { + "code": "java.method.returnTypeTypeParametersChanged", + "old": "method java.util.Iterator com.datastax.oss.driver.api.core.data.CqlVector::iterator()", + "new": "method java.util.Iterator com.datastax.oss.driver.api.core.data.CqlVector::iterator()", + "justification": "Extend driver vector support to arbitrary subtypes for JAVA-3143" + }, + { + "code": "java.method.parameterTypeChanged", + "old": "parameter com.datastax.oss.driver.api.core.data.CqlVector com.datastax.oss.driver.api.core.data.CqlVector::newInstance(===V[]===)", + "new": "parameter com.datastax.oss.driver.api.core.data.CqlVector com.datastax.oss.driver.api.core.data.CqlVector::newInstance(===V[]===)", + "justification": "Extend driver vector support to arbitrary subtypes for JAVA-3143" + }, + { + "code": "java.method.returnTypeTypeParametersChanged", + "old": "method com.datastax.oss.driver.api.core.data.CqlVector com.datastax.oss.driver.api.core.data.CqlVector::newInstance(V[])", + "new": "method com.datastax.oss.driver.api.core.data.CqlVector com.datastax.oss.driver.api.core.data.CqlVector::newInstance(V[])", + "justification": "Extend driver vector support to arbitrary subtypes for JAVA-3143" + }, + { + "code": "java.generics.formalTypeParameterChanged", + "old": "method com.datastax.oss.driver.api.core.data.CqlVector com.datastax.oss.driver.api.core.data.CqlVector::newInstance(V[])", + "new": "method com.datastax.oss.driver.api.core.data.CqlVector com.datastax.oss.driver.api.core.data.CqlVector::newInstance(V[])", + "justification": "Extend driver vector support to arbitrary subtypes for JAVA-3143" + }, + { + "code": "java.method.parameterTypeParameterChanged", + "old": "parameter com.datastax.oss.driver.api.core.data.CqlVector com.datastax.oss.driver.api.core.data.CqlVector::newInstance(===java.util.List===)", + "new": "parameter com.datastax.oss.driver.api.core.data.CqlVector com.datastax.oss.driver.api.core.data.CqlVector::newInstance(===java.util.List===)", + "justification": "Extend driver vector support to arbitrary subtypes for JAVA-3143" + }, + { + "code": "java.method.returnTypeTypeParametersChanged", + "old": "method com.datastax.oss.driver.api.core.data.CqlVector com.datastax.oss.driver.api.core.data.CqlVector::newInstance(java.util.List)", + "new": "method com.datastax.oss.driver.api.core.data.CqlVector com.datastax.oss.driver.api.core.data.CqlVector::newInstance(java.util.List)", + "justification": "Extend driver vector support to arbitrary subtypes for JAVA-3143" + }, + { + "code": "java.generics.formalTypeParameterChanged", + "old": "method com.datastax.oss.driver.api.core.data.CqlVector com.datastax.oss.driver.api.core.data.CqlVector::newInstance(java.util.List)", + "new": "method com.datastax.oss.driver.api.core.data.CqlVector com.datastax.oss.driver.api.core.data.CqlVector::newInstance(java.util.List)", + "justification": "Extend driver vector support to arbitrary subtypes for JAVA-3143" + }, + { + "code": "java.method.parameterTypeChanged", + "old": "parameter T com.datastax.oss.driver.api.core.data.CqlVector::set(int, ===T===)", + "new": "parameter T com.datastax.oss.driver.api.core.data.CqlVector::set(int, ===T===)", + "justification": "Extend driver vector support to arbitrary subtypes for JAVA-3143" + }, + { + "code": "java.method.returnTypeChanged", + "old": "method T com.datastax.oss.driver.api.core.data.CqlVector::set(int, T)", + "new": "method T com.datastax.oss.driver.api.core.data.CqlVector::set(int, T)", + "justification": "Extend driver vector support to arbitrary subtypes for JAVA-3143" + }, + { + "code": "java.method.returnTypeTypeParametersChanged", + "old": "method java.util.Spliterator java.lang.Iterable::spliterator() @ com.datastax.oss.driver.api.core.data.CqlVector", + "new": "method java.util.Spliterator java.lang.Iterable::spliterator() @ com.datastax.oss.driver.api.core.data.CqlVector", + "justification": "Extend driver vector support to arbitrary subtypes for JAVA-3143" + }, + { + "code": "java.method.returnTypeTypeParametersChanged", + "old": "method java.util.stream.Stream com.datastax.oss.driver.api.core.data.CqlVector::stream()", + "new": "method java.util.stream.Stream com.datastax.oss.driver.api.core.data.CqlVector::stream()", + "justification": "Extend driver vector support to arbitrary subtypes for JAVA-3143" + }, + { + "code": "java.method.returnTypeTypeParametersChanged", + "old": "method com.datastax.oss.driver.api.core.data.CqlVector com.datastax.oss.driver.api.core.data.CqlVector::subVector(int, int)", + "new": "method com.datastax.oss.driver.api.core.data.CqlVector com.datastax.oss.driver.api.core.data.CqlVector::subVector(int, int)", + "justification": "Extend driver vector support to arbitrary subtypes for JAVA-3143" + }, + { + "code": "java.class.noLongerImplementsInterface", + "old": "class com.datastax.oss.driver.api.core.data.CqlVector", + "new": "class com.datastax.oss.driver.api.core.data.CqlVector", + "interface": "java.lang.Iterable", + "justification": "Extend driver vector support to arbitrary subtypes for JAVA-3143" + }, + { + "code": "java.generics.formalTypeParameterChanged", + "old": "class com.datastax.oss.driver.api.core.data.CqlVector", + "new": "class com.datastax.oss.driver.api.core.data.CqlVector", + "justification": "Extend driver vector support to arbitrary subtypes for JAVA-3143" + }, + { + "code": "java.class.superTypeTypeParametersChanged", + "old": "class com.datastax.oss.driver.api.core.data.CqlVector", + "new": "class com.datastax.oss.driver.api.core.data.CqlVector", + "oldSuperType": "java.lang.Iterable", + "newSuperType": "java.lang.Iterable", + "justification": "Extend driver vector support to arbitrary subtypes for JAVA-3143" + }, + { + "code": "java.method.parameterTypeParameterChanged", + "old": "parameter com.datastax.oss.driver.api.core.data.CqlVector com.datastax.oss.driver.api.core.data.GettableById::getVector(com.datastax.oss.driver.api.core.CqlIdentifier, ===java.lang.Class===)", + "new": "parameter com.datastax.oss.driver.api.core.data.CqlVector com.datastax.oss.driver.api.core.data.GettableById::getVector(com.datastax.oss.driver.api.core.CqlIdentifier, ===java.lang.Class===)", + "justification": "Extend driver vector support to arbitrary subtypes for JAVA-3143" + }, + { + "code": "java.method.returnTypeTypeParametersChanged", + "old": "method com.datastax.oss.driver.api.core.data.CqlVector com.datastax.oss.driver.api.core.data.GettableById::getVector(com.datastax.oss.driver.api.core.CqlIdentifier, java.lang.Class)", + "new": "method com.datastax.oss.driver.api.core.data.CqlVector com.datastax.oss.driver.api.core.data.GettableById::getVector(com.datastax.oss.driver.api.core.CqlIdentifier, java.lang.Class)", + "justification": "Extend driver vector support to arbitrary subtypes for JAVA-3143" + }, + { + "code": "java.generics.formalTypeParameterChanged", + "old": "method com.datastax.oss.driver.api.core.data.CqlVector com.datastax.oss.driver.api.core.data.GettableById::getVector(com.datastax.oss.driver.api.core.CqlIdentifier, java.lang.Class)", + "new": "method com.datastax.oss.driver.api.core.data.CqlVector com.datastax.oss.driver.api.core.data.GettableById::getVector(com.datastax.oss.driver.api.core.CqlIdentifier, java.lang.Class)", + "justification": "Extend driver vector support to arbitrary subtypes for JAVA-3143" + }, + { + "code": "java.method.parameterTypeParameterChanged", + "old": "parameter com.datastax.oss.driver.api.core.data.CqlVector com.datastax.oss.driver.api.core.data.GettableByIndex::getVector(int, ===java.lang.Class===)", + "new": "parameter com.datastax.oss.driver.api.core.data.CqlVector com.datastax.oss.driver.api.core.data.GettableByIndex::getVector(int, ===java.lang.Class===)", + "justification": "Extend driver vector support to arbitrary subtypes for JAVA-3143" + }, + { + "code": "java.method.returnTypeTypeParametersChanged", + "old": "method com.datastax.oss.driver.api.core.data.CqlVector com.datastax.oss.driver.api.core.data.GettableByIndex::getVector(int, java.lang.Class)", + "new": "method com.datastax.oss.driver.api.core.data.CqlVector com.datastax.oss.driver.api.core.data.GettableByIndex::getVector(int, java.lang.Class)", + "justification": "Extend driver vector support to arbitrary subtypes for JAVA-3143" + }, + { + "code": "java.generics.formalTypeParameterChanged", + "old": "method com.datastax.oss.driver.api.core.data.CqlVector com.datastax.oss.driver.api.core.data.GettableByIndex::getVector(int, java.lang.Class)", + "new": "method com.datastax.oss.driver.api.core.data.CqlVector com.datastax.oss.driver.api.core.data.GettableByIndex::getVector(int, java.lang.Class)", + "justification": "Extend driver vector support to arbitrary subtypes for JAVA-3143" + }, + { + "code": "java.method.parameterTypeParameterChanged", + "old": "parameter com.datastax.oss.driver.api.core.data.CqlVector com.datastax.oss.driver.api.core.data.GettableByName::getVector(java.lang.String, ===java.lang.Class===)", + "new": "parameter com.datastax.oss.driver.api.core.data.CqlVector com.datastax.oss.driver.api.core.data.GettableByName::getVector(java.lang.String, ===java.lang.Class===)", + "justification": "Extend driver vector support to arbitrary subtypes for JAVA-3143" + }, + { + "code": "java.method.returnTypeTypeParametersChanged", + "old": "method com.datastax.oss.driver.api.core.data.CqlVector com.datastax.oss.driver.api.core.data.GettableByName::getVector(java.lang.String, java.lang.Class)", + "new": "method com.datastax.oss.driver.api.core.data.CqlVector com.datastax.oss.driver.api.core.data.GettableByName::getVector(java.lang.String, java.lang.Class)", + "justification": "Extend driver vector support to arbitrary subtypes for JAVA-3143" + }, + { + "code": "java.generics.formalTypeParameterChanged", + "old": "method com.datastax.oss.driver.api.core.data.CqlVector com.datastax.oss.driver.api.core.data.GettableByName::getVector(java.lang.String, java.lang.Class)", + "new": "method com.datastax.oss.driver.api.core.data.CqlVector com.datastax.oss.driver.api.core.data.GettableByName::getVector(java.lang.String, java.lang.Class)", + "justification": "Extend driver vector support to arbitrary subtypes for JAVA-3143" + }, + { + "code": "java.method.parameterTypeParameterChanged", + "old": "parameter SelfT com.datastax.oss.driver.api.core.data.SettableById>::setVector(com.datastax.oss.driver.api.core.CqlIdentifier, ===com.datastax.oss.driver.api.core.data.CqlVector===, java.lang.Class)", + "new": "parameter SelfT com.datastax.oss.driver.api.core.data.SettableById>::setVector(com.datastax.oss.driver.api.core.CqlIdentifier, ===com.datastax.oss.driver.api.core.data.CqlVector===, java.lang.Class)", + "justification": "Extend driver vector support to arbitrary subtypes for JAVA-3143" + }, + { + "code": "java.method.parameterTypeParameterChanged", + "old": "parameter SelfT com.datastax.oss.driver.api.core.data.SettableById>::setVector(com.datastax.oss.driver.api.core.CqlIdentifier, com.datastax.oss.driver.api.core.data.CqlVector, ===java.lang.Class===)", + "new": "parameter SelfT com.datastax.oss.driver.api.core.data.SettableById>::setVector(com.datastax.oss.driver.api.core.CqlIdentifier, com.datastax.oss.driver.api.core.data.CqlVector, ===java.lang.Class===)", + "justification": "Extend driver vector support to arbitrary subtypes for JAVA-3143" + }, + { + "code": "java.generics.formalTypeParameterChanged", + "old": "method SelfT com.datastax.oss.driver.api.core.data.SettableById>::setVector(com.datastax.oss.driver.api.core.CqlIdentifier, com.datastax.oss.driver.api.core.data.CqlVector, java.lang.Class)", + "new": "method SelfT com.datastax.oss.driver.api.core.data.SettableById>::setVector(com.datastax.oss.driver.api.core.CqlIdentifier, com.datastax.oss.driver.api.core.data.CqlVector, java.lang.Class)", + "justification": "Extend driver vector support to arbitrary subtypes for JAVA-3143" + }, + { + "code": "java.method.parameterTypeParameterChanged", + "old": "parameter SelfT com.datastax.oss.driver.api.core.data.SettableByIndex>::setVector(int, ===com.datastax.oss.driver.api.core.data.CqlVector===, java.lang.Class)", + "new": "parameter SelfT com.datastax.oss.driver.api.core.data.SettableByIndex>::setVector(int, ===com.datastax.oss.driver.api.core.data.CqlVector===, java.lang.Class)", + "justification": "Extend driver vector support to arbitrary subtypes for JAVA-3143" + }, + { + "code": "java.method.parameterTypeParameterChanged", + "old": "parameter SelfT com.datastax.oss.driver.api.core.data.SettableByIndex>::setVector(int, com.datastax.oss.driver.api.core.data.CqlVector, ===java.lang.Class===)", + "new": "parameter SelfT com.datastax.oss.driver.api.core.data.SettableByIndex>::setVector(int, com.datastax.oss.driver.api.core.data.CqlVector, ===java.lang.Class===)", + "justification": "Extend driver vector support to arbitrary subtypes for JAVA-3143" + }, + { + "code": "java.generics.formalTypeParameterChanged", + "old": "method SelfT com.datastax.oss.driver.api.core.data.SettableByIndex>::setVector(int, com.datastax.oss.driver.api.core.data.CqlVector, java.lang.Class)", + "new": "method SelfT com.datastax.oss.driver.api.core.data.SettableByIndex>::setVector(int, com.datastax.oss.driver.api.core.data.CqlVector, java.lang.Class)", + "justification": "Extend driver vector support to arbitrary subtypes for JAVA-3143" + }, + { + "code": "java.method.parameterTypeParameterChanged", + "old": "parameter SelfT com.datastax.oss.driver.api.core.data.SettableByName>::setVector(java.lang.String, ===com.datastax.oss.driver.api.core.data.CqlVector===, java.lang.Class)", + "new": "parameter SelfT com.datastax.oss.driver.api.core.data.SettableByName>::setVector(java.lang.String, ===com.datastax.oss.driver.api.core.data.CqlVector===, java.lang.Class)", + "justification": "Extend driver vector support to arbitrary subtypes for JAVA-3143" + }, + { + "code": "java.method.parameterTypeParameterChanged", + "old": "parameter SelfT com.datastax.oss.driver.api.core.data.SettableByName>::setVector(java.lang.String, com.datastax.oss.driver.api.core.data.CqlVector, ===java.lang.Class===)", + "new": "parameter SelfT com.datastax.oss.driver.api.core.data.SettableByName>::setVector(java.lang.String, com.datastax.oss.driver.api.core.data.CqlVector, ===java.lang.Class===)", + "justification": "Extend driver vector support to arbitrary subtypes for JAVA-3143" + }, + { + "code": "java.generics.formalTypeParameterChanged", + "old": "method SelfT com.datastax.oss.driver.api.core.data.SettableByName>::setVector(java.lang.String, com.datastax.oss.driver.api.core.data.CqlVector, java.lang.Class)", + "new": "method SelfT com.datastax.oss.driver.api.core.data.SettableByName>::setVector(java.lang.String, com.datastax.oss.driver.api.core.data.CqlVector, java.lang.Class)", + "justification": "Extend driver vector support to arbitrary subtypes for JAVA-3143" + }, + { + "code": "java.method.parameterTypeParameterChanged", + "old": "parameter com.datastax.oss.driver.api.core.type.codec.TypeCodec> com.datastax.oss.driver.api.core.type.codec.TypeCodecs::vectorOf(com.datastax.oss.driver.api.core.type.VectorType, ===com.datastax.oss.driver.api.core.type.codec.TypeCodec===)", + "new": "parameter com.datastax.oss.driver.api.core.type.codec.TypeCodec> com.datastax.oss.driver.api.core.type.codec.TypeCodecs::vectorOf(com.datastax.oss.driver.api.core.type.VectorType, ===com.datastax.oss.driver.api.core.type.codec.TypeCodec===)", + "justification": "Extend driver vector support to arbitrary subtypes for JAVA-3143" + }, + { + "code": "java.method.returnTypeTypeParametersChanged", + "old": "method com.datastax.oss.driver.api.core.type.codec.TypeCodec> com.datastax.oss.driver.api.core.type.codec.TypeCodecs::vectorOf(com.datastax.oss.driver.api.core.type.VectorType, com.datastax.oss.driver.api.core.type.codec.TypeCodec)", + "new": "method com.datastax.oss.driver.api.core.type.codec.TypeCodec> com.datastax.oss.driver.api.core.type.codec.TypeCodecs::vectorOf(com.datastax.oss.driver.api.core.type.VectorType, com.datastax.oss.driver.api.core.type.codec.TypeCodec)", + "justification": "Extend driver vector support to arbitrary subtypes for JAVA-3143" + }, + { + "code": "java.generics.formalTypeParameterChanged", + "old": "method com.datastax.oss.driver.api.core.type.codec.TypeCodec> com.datastax.oss.driver.api.core.type.codec.TypeCodecs::vectorOf(com.datastax.oss.driver.api.core.type.VectorType, com.datastax.oss.driver.api.core.type.codec.TypeCodec)", + "new": "method com.datastax.oss.driver.api.core.type.codec.TypeCodec> com.datastax.oss.driver.api.core.type.codec.TypeCodecs::vectorOf(com.datastax.oss.driver.api.core.type.VectorType, com.datastax.oss.driver.api.core.type.codec.TypeCodec)", + "justification": "Extend driver vector support to arbitrary subtypes for JAVA-3143" + }, + { + "code": "java.method.parameterTypeParameterChanged", + "old": "parameter com.datastax.oss.driver.api.core.type.codec.TypeCodec> com.datastax.oss.driver.api.core.type.codec.TypeCodecs::vectorOf(int, ===com.datastax.oss.driver.api.core.type.codec.TypeCodec===)", + "new": "parameter com.datastax.oss.driver.api.core.type.codec.TypeCodec> com.datastax.oss.driver.api.core.type.codec.TypeCodecs::vectorOf(int, ===com.datastax.oss.driver.api.core.type.codec.TypeCodec===)", + "justification": "Extend driver vector support to arbitrary subtypes for JAVA-3143" + }, + { + "code": "java.method.returnTypeTypeParametersChanged", + "old": "method com.datastax.oss.driver.api.core.type.codec.TypeCodec> com.datastax.oss.driver.api.core.type.codec.TypeCodecs::vectorOf(int, com.datastax.oss.driver.api.core.type.codec.TypeCodec)", + "new": "method com.datastax.oss.driver.api.core.type.codec.TypeCodec> com.datastax.oss.driver.api.core.type.codec.TypeCodecs::vectorOf(int, com.datastax.oss.driver.api.core.type.codec.TypeCodec)", + "justification": "Extend driver vector support to arbitrary subtypes for JAVA-3143" + }, + { + "code": "java.generics.formalTypeParameterChanged", + "old": "method com.datastax.oss.driver.api.core.type.codec.TypeCodec> com.datastax.oss.driver.api.core.type.codec.TypeCodecs::vectorOf(int, com.datastax.oss.driver.api.core.type.codec.TypeCodec)", + "new": "method com.datastax.oss.driver.api.core.type.codec.TypeCodec> com.datastax.oss.driver.api.core.type.codec.TypeCodecs::vectorOf(int, com.datastax.oss.driver.api.core.type.codec.TypeCodec)", + "justification": "Extend driver vector support to arbitrary subtypes for JAVA-3143" + }, + { + "code": "java.method.parameterTypeParameterChanged", + "old": "parameter com.datastax.oss.driver.api.core.type.reflect.GenericType> com.datastax.oss.driver.api.core.type.reflect.GenericType::vectorOf(===com.datastax.oss.driver.api.core.type.reflect.GenericType===)", + "new": "parameter com.datastax.oss.driver.api.core.type.reflect.GenericType> com.datastax.oss.driver.api.core.type.reflect.GenericType::vectorOf(===com.datastax.oss.driver.api.core.type.reflect.GenericType===)", + "justification": "Extend driver vector support to arbitrary subtypes for JAVA-3143" + }, + { + "code": "java.method.returnTypeTypeParametersChanged", + "old": "method com.datastax.oss.driver.api.core.type.reflect.GenericType> com.datastax.oss.driver.api.core.type.reflect.GenericType::vectorOf(com.datastax.oss.driver.api.core.type.reflect.GenericType)", + "new": "method com.datastax.oss.driver.api.core.type.reflect.GenericType> com.datastax.oss.driver.api.core.type.reflect.GenericType::vectorOf(com.datastax.oss.driver.api.core.type.reflect.GenericType)", + "justification": "Extend driver vector support to arbitrary subtypes for JAVA-3143" + }, + { + "code": "java.generics.formalTypeParameterChanged", + "old": "method com.datastax.oss.driver.api.core.type.reflect.GenericType> com.datastax.oss.driver.api.core.type.reflect.GenericType::vectorOf(com.datastax.oss.driver.api.core.type.reflect.GenericType)", + "new": "method com.datastax.oss.driver.api.core.type.reflect.GenericType> com.datastax.oss.driver.api.core.type.reflect.GenericType::vectorOf(com.datastax.oss.driver.api.core.type.reflect.GenericType)", + "justification": "Extend driver vector support to arbitrary subtypes for JAVA-3143" + }, + { + "code": "java.method.parameterTypeParameterChanged", + "old": "parameter com.datastax.oss.driver.api.core.type.reflect.GenericType> com.datastax.oss.driver.api.core.type.reflect.GenericType::vectorOf(===java.lang.Class===)", + "new": "parameter com.datastax.oss.driver.api.core.type.reflect.GenericType> com.datastax.oss.driver.api.core.type.reflect.GenericType::vectorOf(===java.lang.Class===)", + "justification": "Extend driver vector support to arbitrary subtypes for JAVA-3143" + }, + { + "code": "java.method.returnTypeTypeParametersChanged", + "old": "method com.datastax.oss.driver.api.core.type.reflect.GenericType> com.datastax.oss.driver.api.core.type.reflect.GenericType::vectorOf(java.lang.Class)", + "new": "method com.datastax.oss.driver.api.core.type.reflect.GenericType> com.datastax.oss.driver.api.core.type.reflect.GenericType::vectorOf(java.lang.Class)", + "justification": "Extend driver vector support to arbitrary subtypes for JAVA-3143" + }, + { + "code": "java.generics.formalTypeParameterChanged", + "old": "method com.datastax.oss.driver.api.core.type.reflect.GenericType> com.datastax.oss.driver.api.core.type.reflect.GenericType::vectorOf(java.lang.Class)", + "new": "method com.datastax.oss.driver.api.core.type.reflect.GenericType> com.datastax.oss.driver.api.core.type.reflect.GenericType::vectorOf(java.lang.Class)", + "justification": "Extend driver vector support to arbitrary subtypes for JAVA-3143" } ] } From aaf7fffc604d00b51542296fb51cdb0b59f20907 Mon Sep 17 00:00:00 2001 From: janehe Date: Wed, 4 Sep 2024 22:48:58 -0800 Subject: [PATCH 23/24] add revapi.json for query builder --- query-builder/revapi.json | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/query-builder/revapi.json b/query-builder/revapi.json index 9d0163b487e..11b98d675e1 100644 --- a/query-builder/revapi.json +++ b/query-builder/revapi.json @@ -2772,6 +2772,11 @@ "code": "java.method.addedToInterface", "new": "method com.datastax.oss.driver.api.querybuilder.update.UpdateStart com.datastax.oss.driver.api.querybuilder.update.UpdateStart::usingTtl(int)", "justification": "JAVA-2210: Add ability to set TTL for modification queries" + }, + { + "code": "java.method.addedToInterface", + "new": "method com.datastax.oss.driver.api.querybuilder.select.Select com.datastax.oss.driver.api.querybuilder.select.Select::orderBy(com.datastax.oss.driver.api.querybuilder.select.Ann)", + "justification": "Extend driver vector support to arbitrary subtypes for JAVA-3143" } ] } From 7ef44b616e4c3fdc60e37515e902c7371052836e Mon Sep 17 00:00:00 2001 From: janehe Date: Thu, 5 Sep 2024 16:00:50 -0800 Subject: [PATCH 24/24] fix failed tests --- .../internal/core/type/DefaultVectorType.java | 2 +- .../oss/driver/api/core/data/CqlVectorTest.java | 17 +++++++++-------- .../api/querybuilder/schema/AlterTableTest.java | 2 +- .../api/querybuilder/schema/AlterTypeTest.java | 2 +- .../querybuilder/schema/CreateTableTest.java | 2 +- .../api/querybuilder/schema/CreateTypeTest.java | 2 +- 6 files changed, 14 insertions(+), 13 deletions(-) diff --git a/core/src/main/java/com/datastax/oss/driver/internal/core/type/DefaultVectorType.java b/core/src/main/java/com/datastax/oss/driver/internal/core/type/DefaultVectorType.java index 38b5720cc1a..ea20b96bbd7 100644 --- a/core/src/main/java/com/datastax/oss/driver/internal/core/type/DefaultVectorType.java +++ b/core/src/main/java/com/datastax/oss/driver/internal/core/type/DefaultVectorType.java @@ -61,7 +61,7 @@ public String getClassName() { @Override public String asCql(boolean includeFrozen, boolean pretty) { return String.format( - "VECTOR<%s, %d>", this.subtype.asCql(includeFrozen, pretty).toLowerCase(), getDimensions()); + "vector<%s, %d>", this.subtype.asCql(includeFrozen, pretty).toLowerCase(), getDimensions()); } /* ============== General class implementation ============== */ diff --git a/core/src/test/java/com/datastax/oss/driver/api/core/data/CqlVectorTest.java b/core/src/test/java/com/datastax/oss/driver/api/core/data/CqlVectorTest.java index 82290d545df..9aba4b6b946 100644 --- a/core/src/test/java/com/datastax/oss/driver/api/core/data/CqlVectorTest.java +++ b/core/src/test/java/com/datastax/oss/driver/api/core/data/CqlVectorTest.java @@ -133,7 +133,6 @@ public void should_throw_when_building_with_nulls() { @Test public void should_build_empty_vector() { - CqlVector vector = CqlVector.newInstance(); assertThat(vector.isEmpty()).isTrue(); assertThat(vector.size()).isEqualTo(0); @@ -142,15 +141,16 @@ public void should_build_empty_vector() { @Test @UseDataProvider("dataProvider") public void should_behave_mostly_like_a_list(T[] vals) { - CqlVector vector = CqlVector.newInstance(vals); - assertThat(vector.get(0)).isEqualTo(vals[0]); - vector.set(0, vals[1]); - assertThat(vector.get(0)).isEqualTo(vals[1]); + T[] theArray = Arrays.copyOf(vals, vals.length); + CqlVector vector = CqlVector.newInstance(theArray); + assertThat(vector.get(0)).isEqualTo(theArray[0]); + vector.set(0, theArray[1]); + assertThat(vector.get(0)).isEqualTo(theArray[1]); assertThat(vector.isEmpty()).isFalse(); assertThat(vector.size()).isEqualTo(2); Iterator iterator = vector.iterator(); - assertThat(iterator.next()).isEqualTo(vals[1]); - assertThat(iterator.next()).isEqualTo(vals[1]); + assertThat(iterator.next()).isEqualTo(theArray[1]); + assertThat(iterator.next()).isEqualTo(theArray[1]); } @Test @@ -182,7 +182,8 @@ public void should_reflect_changes_to_mutable_list(T[] vals) { @Test @UseDataProvider("dataProvider") - public void should_reflect_changes_to_array(T[] theArray) { + public void should_reflect_changes_to_array(T[] vals) { + T[] theArray = Arrays.copyOf(vals, vals.length); CqlVector vector = CqlVector.newInstance(theArray); assertThat(vector.size()).isEqualTo(2); assertThat(vector.get(1)).isEqualTo(theArray[1]); diff --git a/query-builder/src/test/java/com/datastax/oss/driver/api/querybuilder/schema/AlterTableTest.java b/query-builder/src/test/java/com/datastax/oss/driver/api/querybuilder/schema/AlterTableTest.java index 499e2e08572..3ca434737e2 100644 --- a/query-builder/src/test/java/com/datastax/oss/driver/api/querybuilder/schema/AlterTableTest.java +++ b/query-builder/src/test/java/com/datastax/oss/driver/api/querybuilder/schema/AlterTableTest.java @@ -117,6 +117,6 @@ public void should_generate_alter_table_with_vector() { "v", DataTypes.custom( "org.apache.cassandra.db.marshal.VectorType(org.apache.cassandra.db.marshal.FloatType,3)"))) - .hasCql("ALTER TABLE bar ALTER v TYPE VECTOR"); + .hasCql("ALTER TABLE bar ALTER v TYPE vector"); } } diff --git a/query-builder/src/test/java/com/datastax/oss/driver/api/querybuilder/schema/AlterTypeTest.java b/query-builder/src/test/java/com/datastax/oss/driver/api/querybuilder/schema/AlterTypeTest.java index 570dc9e6d6f..45bf280ff23 100644 --- a/query-builder/src/test/java/com/datastax/oss/driver/api/querybuilder/schema/AlterTypeTest.java +++ b/query-builder/src/test/java/com/datastax/oss/driver/api/querybuilder/schema/AlterTypeTest.java @@ -58,6 +58,6 @@ public void should_generate_alter_table_with_rename_three_columns() { @Test public void should_generate_alter_type_with_vector() { assertThat(alterType("foo", "bar").alterField("vec", new DefaultVectorType(DataTypes.FLOAT, 3))) - .hasCql("ALTER TYPE foo.bar ALTER vec TYPE VECTOR"); + .hasCql("ALTER TYPE foo.bar ALTER vec TYPE vector"); } } diff --git a/query-builder/src/test/java/com/datastax/oss/driver/api/querybuilder/schema/CreateTableTest.java b/query-builder/src/test/java/com/datastax/oss/driver/api/querybuilder/schema/CreateTableTest.java index 6d8fd538e01..877275b912f 100644 --- a/query-builder/src/test/java/com/datastax/oss/driver/api/querybuilder/schema/CreateTableTest.java +++ b/query-builder/src/test/java/com/datastax/oss/driver/api/querybuilder/schema/CreateTableTest.java @@ -315,6 +315,6 @@ public void should_generate_vector_column() { createTable("foo") .withPartitionKey("k", DataTypes.INT) .withColumn("v", new DefaultVectorType(DataTypes.FLOAT, 3))) - .hasCql("CREATE TABLE foo (k int PRIMARY KEY,v VECTOR)"); + .hasCql("CREATE TABLE foo (k int PRIMARY KEY,v vector)"); } } diff --git a/query-builder/src/test/java/com/datastax/oss/driver/api/querybuilder/schema/CreateTypeTest.java b/query-builder/src/test/java/com/datastax/oss/driver/api/querybuilder/schema/CreateTypeTest.java index 3c9897ef17f..3fc3c23d1de 100644 --- a/query-builder/src/test/java/com/datastax/oss/driver/api/querybuilder/schema/CreateTypeTest.java +++ b/query-builder/src/test/java/com/datastax/oss/driver/api/querybuilder/schema/CreateTypeTest.java @@ -91,6 +91,6 @@ public void should_create_type_with_vector() { createType("ks1", "type") .withField("c1", DataTypes.INT) .withField("vec", new DefaultVectorType(DataTypes.FLOAT, 3))) - .hasCql("CREATE TYPE ks1.type (c1 int,vec VECTOR)"); + .hasCql("CREATE TYPE ks1.type (c1 int,vec vector)"); } }