cassandra-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From jasobr...@apache.org
Subject [6/6] cassandra git commit: Merge branch 'cassandra-3.11' into trunk
Date Tue, 12 Sep 2017 21:18:44 GMT
Merge branch 'cassandra-3.11' into trunk


Project: http://git-wip-us.apache.org/repos/asf/cassandra/repo
Commit: http://git-wip-us.apache.org/repos/asf/cassandra/commit/c6cd8246
Tree: http://git-wip-us.apache.org/repos/asf/cassandra/tree/c6cd8246
Diff: http://git-wip-us.apache.org/repos/asf/cassandra/diff/c6cd8246

Branch: refs/heads/trunk
Commit: c6cd8246280acde5e2244d8960b2d5c17353424f
Parents: 7d4d1a3 cb2a1c8
Author: Jason Brown <jasedbrown@gmail.com>
Authored: Tue Sep 12 14:14:54 2017 -0700
Committer: Jason Brown <jasedbrown@gmail.com>
Committed: Tue Sep 12 14:18:00 2017 -0700

----------------------------------------------------------------------
 CHANGES.txt                                     |  1 +
 src/java/org/apache/cassandra/cql3/Tuples.java  | 28 ++++++++++++++------
 .../cql3/validation/entities/TupleTypeTest.java | 17 +++++++++++-
 3 files changed, 37 insertions(+), 9 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cassandra/blob/c6cd8246/CHANGES.txt
----------------------------------------------------------------------

http://git-wip-us.apache.org/repos/asf/cassandra/blob/c6cd8246/src/java/org/apache/cassandra/cql3/Tuples.java
----------------------------------------------------------------------
diff --cc src/java/org/apache/cassandra/cql3/Tuples.java
index bae756a,01f3466..317e192
--- a/src/java/org/apache/cassandra/cql3/Tuples.java
+++ b/src/java/org/apache/cassandra/cql3/Tuples.java
@@@ -68,12 -65,7 +68,12 @@@ public class Tuple
  
          public Term prepare(String keyspace, ColumnSpecification receiver) throws InvalidRequestException
          {
 -            validateAssignableTo(keyspace, receiver);
 +            // The parser cannot differentiate between a tuple with one element and a term
between parenthesis.
 +            // By consequence, we need to wait until we know the target type to determine
which one it is.
-             if (elements.size() == 1 && !(receiver.type instanceof TupleType))
++            if (elements.size() == 1 && !checkIfTupleType(receiver.type))
 +                return elements.get(0).prepare(keyspace, receiver);
 +
 +            validateTupleAssignableTo(receiver, elements);
  
              List<Term> values = new ArrayList<>(elements.size());
              boolean allTerminal = true;
@@@ -110,14 -102,38 +110,14 @@@
              return allTerminal ? value.bind(QueryOptions.DEFAULT) : value;
          }
  
 -        private void validateAssignableTo(String keyspace, ColumnSpecification receiver)
throws InvalidRequestException
 -        {
 -            if (!checkIfTupleType(receiver.type))
 -                throw new InvalidRequestException(String.format("Invalid tuple type literal
for %s of type %s", receiver.name, receiver.type.asCQL3Type()));
 -
 -            TupleType tt = getTupleType(receiver.type);
 -            for (int i = 0; i < elements.size(); i++)
 -            {
 -                if (i >= tt.size())
 -                {
 -                    throw new InvalidRequestException(String.format("Invalid tuple literal
for %s: too many elements. Type %s expects %d but got %d",
 -                            receiver.name, tt.asCQL3Type(), tt.size(), elements.size()));
 -                }
 -
 -                Term.Raw value = elements.get(i);
 -                ColumnSpecification spec = componentSpecOf(receiver, i);
 -                if (!value.testAssignment(keyspace, spec).isAssignable())
 -                    throw new InvalidRequestException(String.format("Invalid tuple literal
for %s: component %d is not of type %s", receiver.name, i, spec.type.asCQL3Type()));
 -            }
 -        }
 -
          public AssignmentTestable.TestResult testAssignment(String keyspace, ColumnSpecification
receiver)
          {
 -            try
 -            {
 -                validateAssignableTo(keyspace, receiver);
 -                return AssignmentTestable.TestResult.WEAKLY_ASSIGNABLE;
 -            }
 -            catch (InvalidRequestException e)
 -            {
 -                return AssignmentTestable.TestResult.NOT_ASSIGNABLE;
 -            }
 +            // The parser cannot differentiate between a tuple with one element and a term
between parenthesis.
 +            // By consequence, we need to wait until we know the target type to determine
which one it is.
-             if (elements.size() == 1 && !(receiver.type instanceof TupleType))
++            if (elements.size() == 1 && !checkIfTupleType(receiver.type))
 +                return elements.get(0).testAssignment(keyspace, receiver);
 +
 +            return testTupleAssignment(receiver, elements);
          }
  
          @Override
@@@ -420,100 -436,29 +420,112 @@@
          }
      }
  
 -    public static String tupleToString(List<?> items)
 +    /**
 +     * Create a <code>String</code> representation of the tuple containing the
specified elements.
 +     *
 +     * @param elements the tuple elements
 +     * @return a <code>String</code> representation of the tuple
 +     */
 +    public static String tupleToString(List<?> elements)
 +    {
 +        return tupleToString(elements, Object::toString);
 +    }
 +
 +    /**
 +     * Create a <code>String</code> representation of the tuple from the specified
items associated to
 +     * the tuples elements.
 +     *
 +     * @param items items associated to the tuple elements
 +     * @param mapper the mapper used to map the items to the <code>String</code>
representation of the tuple elements
 +     * @return a <code>String</code> representation of the tuple
 +     */
 +    public static <T> String tupleToString(Iterable<T> items, java.util.function.Function<T,
String> mapper)
 +    {
 +        return StreamSupport.stream(items.spliterator(), false)
 +                            .map(e -> mapper.apply(e))
 +                            .collect(Collectors.joining(", ", "(", ")"));
 +    }
 +
 +    /**
 +     * Returns the exact TupleType from the items if it can be known.
 +     *
 +     * @param items the items mapped to the tuple elements
 +     * @param mapper the mapper used to retrieve the element types from the  items
 +     * @return the exact TupleType from the items if it can be known or <code>null</code>
 +     */
 +    public static <T> AbstractType<?> getExactTupleTypeIfKnown(List<T>
items,
 +                                                               java.util.function.Function<T,
AbstractType<?>> mapper)
 +    {
 +        List<AbstractType<?>> types = new ArrayList<>(items.size());
 +        for (T item : items)
 +        {
 +            AbstractType<?> type = mapper.apply(item);
 +            if (type == null)
 +                return null;
 +            types.add(type);
 +        }
 +        return new TupleType(types);
 +    }
 +
 +    /**
 +     * Checks if the tuple with the specified elements can be assigned to the specified
column.
 +     *
 +     * @param receiver the receiving column
 +     * @param elements the tuple elements
 +     * @throws InvalidRequestException if the tuple cannot be assigned to the specified
column.
 +     */
 +    public static void validateTupleAssignableTo(ColumnSpecification receiver,
 +                                                 List<? extends AssignmentTestable>
elements)
      {
-         if (!(receiver.type instanceof TupleType))
++        if (!checkIfTupleType(receiver.type))
 +            throw invalidRequest("Invalid tuple type literal for %s of type %s", receiver.name,
receiver.type.asCQL3Type());
  
-         TupleType tt = (TupleType)receiver.type;
 -        StringBuilder sb = new StringBuilder("(");
 -        for (int i = 0; i < items.size(); i++)
++        TupleType tt = getTupleType(receiver.type);
 +        for (int i = 0; i < elements.size(); i++)
 +        {
 +            if (i >= tt.size())
 +            {
 +                throw invalidRequest("Invalid tuple literal for %s: too many elements. Type
%s expects %d but got %d",
 +                                     receiver.name, tt.asCQL3Type(), tt.size(), elements.size());
 +            }
 +
 +            AssignmentTestable value = elements.get(i);
 +            ColumnSpecification spec = componentSpecOf(receiver, i);
 +            if (!value.testAssignment(receiver.ksName, spec).isAssignable())
 +                throw invalidRequest("Invalid tuple literal for %s: component %d is not
of type %s",
 +                                     receiver.name, i, spec.type.asCQL3Type());
 +        }
 +    }
 +
 +    /**
 +     * Tests that the tuple with the specified elements can be assigned to the specified
column.
 +     *
 +     * @param receiver the receiving column
 +     * @param elements the tuple elements
 +     */
 +    public static AssignmentTestable.TestResult testTupleAssignment(ColumnSpecification
receiver,
 +                                                                    List<? extends AssignmentTestable>
elements)
 +    {
 +        try
 +        {
 +            validateTupleAssignableTo(receiver, elements);
 +            return AssignmentTestable.TestResult.WEAKLY_ASSIGNABLE;
 +        }
 +        catch (InvalidRequestException e)
          {
 -            sb.append(items.get(i));
 -            if (i < items.size() - 1)
 -                sb.append(", ");
 +            return AssignmentTestable.TestResult.NOT_ASSIGNABLE;
          }
 -        sb.append(')');
 -        return sb.toString();
      }
+ 
+     public static boolean checkIfTupleType(AbstractType<?> tuple)
+     {
+         return (tuple instanceof TupleType) ||
+                (tuple instanceof ReversedType && ((ReversedType) tuple).baseType
instanceof TupleType);
+ 
+     }
+ 
+     public static TupleType getTupleType(AbstractType<?> tuple)
+     {
+         return (tuple instanceof ReversedType ? ((TupleType) ((ReversedType) tuple).baseType)
: (TupleType)tuple);
+     }
  }

http://git-wip-us.apache.org/repos/asf/cassandra/blob/c6cd8246/test/unit/org/apache/cassandra/cql3/validation/entities/TupleTypeTest.java
----------------------------------------------------------------------
diff --cc test/unit/org/apache/cassandra/cql3/validation/entities/TupleTypeTest.java
index 4dc8d18,bace751..28430cb
--- a/test/unit/org/apache/cassandra/cql3/validation/entities/TupleTypeTest.java
+++ b/test/unit/org/apache/cassandra/cql3/validation/entities/TupleTypeTest.java
@@@ -213,10 -217,12 +217,21 @@@ public class TupleTypeTest extends CQLT
      }
  
      @Test
 +    public void testTupleModification() throws Throwable
 +    {
 +        createTable("CREATE TABLE %s(pk int PRIMARY KEY, value tuple<int, int>)");
 +        assertInvalidMessage("Invalid operation (value = value + (1, 1)) for tuple column
value",
 +                             "UPDATE %s SET value += (1, 1) WHERE k=0;");
 +    }
- }
++
++    @Test
+     public void testReversedTypeTuple() throws Throwable
+     {
+         // CASSANDRA-13717
+         createTable("CREATE TABLE %s (id int, tdemo frozen<tuple<timestamp, varchar>>,
primary key (id, tdemo)) with clustering order by (tdemo desc)");
+         execute("INSERT INTO %s (id, tdemo) VALUES (1, ('2017-02-03 03:05+0000','Europe'))");
+         DateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mmX", Locale.ENGLISH);
+         assertRows(execute("SELECT tdemo FROM %s"), row(tuple( df.parse("2017-02-03 03:05+0000"),
"Europe")));
+     }
+ }
++


---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@cassandra.apache.org
For additional commands, e-mail: commits-help@cassandra.apache.org


Mime
View raw message