Maxwell-Guo commented on code in PR #2436:
URL: https://github.com/apache/cassandra/pull/2436#discussion_r1243070743


##########
src/java/org/apache/cassandra/cql3/functions/types/VectorCodec.java:
##########
@@ -0,0 +1,211 @@
+/*
+ * 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 org.apache.cassandra.cql3.functions.types;
+
+import java.nio.ByteBuffer;
+import java.util.Iterator;
+import java.util.List;
+
+import com.google.common.base.Splitter;
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.Iterables;
+
+import 
org.apache.cassandra.cql3.functions.types.exceptions.InvalidTypeException;
+import org.apache.cassandra.transport.ProtocolVersion;
+import org.apache.cassandra.utils.vint.VIntCoding;
+
+/**
+ * {@link TypeCodec} for vectors. Vectors are represented as {@link List}s for 
convenience, since it's probably easier
+ * for UDFs trying to return a newly created vector to create it as a standard 
Java list, rather than using a custom,
+ * not-standard vector class.
+ *
+ * @param <E> The type of the vector elements.
+ */
+public abstract class VectorCodec<E> extends TypeCodec<List<E>>
+{
+    protected final VectorType type;
+    protected final TypeCodec<E> subtypeCodec;
+
+    private VectorCodec(VectorType type, TypeCodec<E> subtypeCodec)
+    {
+        super(type, TypeTokens.vectorOf(subtypeCodec.getJavaType()));
+        this.type = type;
+        this.subtypeCodec = subtypeCodec;
+    }
+
+    public static <E> VectorCodec<E> of(VectorType type, TypeCodec<E> 
subtypeCodec)
+    {
+        return subtypeCodec.isValueLengthFixed()
+               ? new FixedLength<>(type, subtypeCodec)
+               : new VariableLength<>(type, subtypeCodec);
+    }
+
+    @Override
+    public List<E> parse(String value) throws InvalidTypeException
+    {
+        if (value == null || value.isEmpty() || 
value.equalsIgnoreCase("NULL")) return null;
+
+        ImmutableList.Builder<E> values = ImmutableList.builder();
+        for (String element : Splitter.on(", ").split(value.substring(1, 
value.length() - 1)))

Review Comment:
   ok



##########
test/unit/org/apache/cassandra/cql3/validation/operations/CQLVectorTest.java:
##########
@@ -248,25 +250,103 @@ public void token()
     @Test
     public void udf() throws Throwable
     {
-        // For future authors, if this test starts to fail as vectors become 
supported in UDFs, please update this test
-        // to test the integration and remove the requirement that we reject 
UDFs all together
         createTable(KEYSPACE, "CREATE TABLE %s (pk int primary key, value 
vector<int, 2>)");
-        Assertions.assertThatThrownBy(() -> createFunction(KEYSPACE,
-                                                           "",
-                                                           "CREATE FUNCTION %s 
(x vector<int, 2>) " +
-                                                           "CALLED ON NULL 
INPUT " +
-                                                           "RETURNS 
vector<int, 2> " +
-                                                           "LANGUAGE java " +
-                                                           "AS 'return x;'"))
-                  .hasRootCauseMessage("Vectors are not supported on UDFs; 
given vector<int, 2>");
-
-        Assertions.assertThatThrownBy(() -> createFunction(KEYSPACE,
-                                                           "",
-                                                           "CREATE FUNCTION %s 
(x list<vector<int, 2>>) " +
-                                                           "CALLED ON NULL 
INPUT " +
-                                                           "RETURNS 
list<vector<int, 2>> " +
-                                                           "LANGUAGE java " +
-                                                           "AS 'return x;'"))
-                  .hasRootCauseMessage("Vectors are not supported on UDFs; 
given list<vector<int, 2>>");
+        Vector<Integer> vector = vector(1, 2);
+        execute("INSERT INTO %s (pk, value) VALUES (0, ?)", vector);
+
+        // identitiy function
+        String f =  createFunction(KEYSPACE,
+                                   "",
+                                   "CREATE FUNCTION %s (x vector<int, 2>) " +
+                                   "CALLED ON NULL INPUT " +
+                                   "RETURNS vector<int, 2> " +
+                                   "LANGUAGE java " +
+                                   "AS 'return x;'");
+        assertRows(execute(format("SELECT %s(value) FROM %%s", f)), 
row(vector));
+        assertRows(execute(format("SELECT %s([2, 3]) FROM %%s", f)), 
row(vector(2, 3)));
+        assertRows(execute(format("SELECT %s(null) FROM %%s", f)), 
row((Vector<Integer>) null));
+
+        // identitiy function with nested type
+        f = createFunction(KEYSPACE,
+                           "",
+                           "CREATE FUNCTION %s (x list<vector<int, 2>>) " +
+                           "CALLED ON NULL INPUT " +
+                           "RETURNS list<vector<int, 2>> " +
+                           "LANGUAGE java " +
+                           "AS 'return x;'");
+        assertRows(execute(format("SELECT %s([value]) FROM %%s", f)), 
row(list(vector)));
+        assertRows(execute(format("SELECT %s([[2, 3]]) FROM %%s", f)), 
row(list(vector(2, 3))));
+        assertRows(execute(format("SELECT %s(null) FROM %%s", f)), 
row((Vector<Integer>) null));
+
+        // identitiy function with elements of variable length
+        f =  createFunction(KEYSPACE,
+                            "",
+                            "CREATE FUNCTION %s (x vector<text, 2>) " +
+                            "CALLED ON NULL INPUT " +
+                            "RETURNS vector<text, 2> " +
+                            "LANGUAGE java " +
+                            "AS 'return x;'");
+        assertRows(execute(format("SELECT %s(['abc', 'defghij']) FROM %%s", 
f)), row(vector("abc", "defghij")));
+        assertRows(execute(format("SELECT %s(null) FROM %%s", f)), 
row((Vector<Integer>) null));
+
+        // function accessing vector argument elements
+        f = createFunction(KEYSPACE,
+                           "",
+                           "CREATE FUNCTION %s (x vector<int, 2>, i int) " +
+                           "CALLED ON NULL INPUT " +
+                           "RETURNS int " +
+                           "LANGUAGE java " +
+                           "AS 'return x == null ? null : x.get(i);'");
+        assertRows(execute(format("SELECT %s(value, 0), %<s(value, 1) FROM 
%%s", f)), row(1, 2));
+        assertRows(execute(format("SELECT %s([2, 3], 0), %<s([2, 3], 1) FROM 
%%s", f)), row(2, 3));
+        assertRows(execute(format("SELECT %s(null, 0) FROM %%s", f)), 
row((Integer) null));
+
+        // function accessing vector argument dimensions
+        f = createFunction(KEYSPACE,
+                           "",
+                           "CREATE FUNCTION %s (x vector<int, 2>) " +
+                           "CALLED ON NULL INPUT " +
+                           "RETURNS int " +
+                           "LANGUAGE java " +
+                           "AS 'return x == null ? 0 : x.size();'");
+        assertRows(execute(format("SELECT %s(value) FROM %%s", f)), row(2));
+        assertRows(execute(format("SELECT %s([2, 3]) FROM %%s", f)), row(2));
+        assertRows(execute(format("SELECT %s(null) FROM %%s", f)), row(0));
+
+        // build vector with elements of fixed length
+        f = createFunction(KEYSPACE,
+                           "",
+                           "CREATE FUNCTION %s () " +
+                           "CALLED ON NULL INPUT " +
+                           "RETURNS vector<double, 3> " +
+                           "LANGUAGE java " +
+                           "AS 'return Arrays.asList(1.3, 2.2, 3.1);'");
+        assertRows(execute(format("SELECT %s() FROM %%s", f)), row(vector(1.3, 
2.2, 3.1)));
+
+        // build vector with elements of varaible length
+        f = createFunction(KEYSPACE,
+                           "",
+                           "CREATE FUNCTION %s () " +
+                           "CALLED ON NULL INPUT " +
+                           "RETURNS vector<text, 3> " +
+                           "LANGUAGE java " +
+                           "AS 'return Arrays.asList(\"a\", \"bc\", 
\"def\");'");
+        assertRows(execute(format("SELECT %s() FROM %%s", f)), row(vector("a", 
"bc", "def")));
+
+        // concat vectors, just to put it all together
+        f =  createFunction(KEYSPACE,
+                            "",
+                            "CREATE FUNCTION %s (x vector<int, 2>, y 
vector<int, 2>) " +
+                            "CALLED ON NULL INPUT " +
+                            "RETURNS vector<int, 4> " +
+                            "LANGUAGE java " +
+                            "AS '" +
+                            "if (x == null || y == null) return null;" +
+                            "List<Integer> l = new ArrayList<Integer>(x); " +
+                            "l.addAll(y); " +
+                            "return l;'");
+        assertRows(execute(format("SELECT %s(value, [3, 4]) FROM %%s", f)), 
row(vector(1, 2, 3, 4)));
+        assertRows(execute(format("SELECT %s([2, 3], value) FROM %%s", f)), 
row(vector(2, 3, 1, 2)));
+        assertRows(execute(format("SELECT %s(null, null) FROM %%s", f)), 
row((Vector<Integer>) null));

Review Comment:
   thanks



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to