You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cassandra.apache.org by sl...@apache.org on 2014/07/07 18:06:38 UTC

[1/4] git commit: Fix error when CONTAINS is used with a bind marker

Repository: cassandra
Updated Branches:
  refs/heads/trunk d13a996e4 -> e28cc6354


Fix error when CONTAINS is used with a bind marker

patch by slebresne; reviewed by tjake for CASSANDRA-7502


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

Branch: refs/heads/trunk
Commit: 0c6fad4a8a8d30198283f36f35077d52e8122cee
Parents: cbe4fd0
Author: Sylvain Lebresne <sy...@datastax.com>
Authored: Mon Jul 7 17:31:44 2014 +0200
Committer: Sylvain Lebresne <sy...@datastax.com>
Committed: Mon Jul 7 17:31:44 2014 +0200

----------------------------------------------------------------------
 CHANGES.txt                                     |   3 +-
 .../cql3/statements/SelectStatement.java        |   1 +
 .../org/apache/cassandra/cql3/CQLTester.java    |  52 +++++++++
 .../cassandra/cql3/ContainsRelationTest.java    | 106 +++++++++++--------
 4 files changed, 117 insertions(+), 45 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cassandra/blob/0c6fad4a/CHANGES.txt
----------------------------------------------------------------------
diff --git a/CHANGES.txt b/CHANGES.txt
index b609795..095624d 100644
--- a/CHANGES.txt
+++ b/CHANGES.txt
@@ -1,4 +1,4 @@
-2.1.0
+2.1.0-rc3
  * Fix ClassCastException processing expired messages (CASSANDRA-7496)
  * Fix prepared marker for collections inside UDT (CASSANDRA-7472)
  * Remove left-over populate_io_cache_on_flush and replicate_on_write
@@ -7,6 +7,7 @@
  * Ensure writes have completed after dropping a table, before recycling
    commit log segments (CASSANDRA-7437)
  * Remove left-over rows_per_partition_to_cache (CASSANDRA-7493)
+ * Fix error when CONTAINS is used with a bind marker (CASSANDRA-7502)
 Merged from 2.0:
  * Fix CC#collectTimeOrderedData() tombstone optimisations (CASSANDRA-7394)
  * Support DISTINCT for static columns and fix behaviour when DISTINC is

http://git-wip-us.apache.org/repos/asf/cassandra/blob/0c6fad4a/src/java/org/apache/cassandra/cql3/statements/SelectStatement.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/cql3/statements/SelectStatement.java b/src/java/org/apache/cassandra/cql3/statements/SelectStatement.java
index b454ece..c9572c2 100644
--- a/src/java/org/apache/cassandra/cql3/statements/SelectStatement.java
+++ b/src/java/org/apache/cassandra/cql3/statements/SelectStatement.java
@@ -1697,6 +1697,7 @@ public class SelectStatement implements CQLStatement, MeasurableForPreparedCache
                     boolean isKey = newRel.operator() == Relation.Type.CONTAINS_KEY;
                     receiver = makeCollectionReceiver(receiver, isKey);
                     Term t = newRel.getValue().prepare(keyspace(), receiver);
+                    t.collectMarkerSpecification(boundNames);
                     ((SingleColumnRestriction.Contains)existingRestriction).add(t, isKey);
                 }
             }

http://git-wip-us.apache.org/repos/asf/cassandra/blob/0c6fad4a/test/unit/org/apache/cassandra/cql3/CQLTester.java
----------------------------------------------------------------------
diff --git a/test/unit/org/apache/cassandra/cql3/CQLTester.java b/test/unit/org/apache/cassandra/cql3/CQLTester.java
index b8912e7..b861d49 100644
--- a/test/unit/org/apache/cassandra/cql3/CQLTester.java
+++ b/test/unit/org/apache/cassandra/cql3/CQLTester.java
@@ -25,6 +25,7 @@ import java.util.concurrent.TimeUnit;
 import java.util.concurrent.atomic.AtomicInteger;
 
 import com.google.common.base.Objects;
+import com.google.common.collect.ImmutableSet;
 import org.junit.AfterClass;
 import org.junit.After;
 import org.junit.Assert;
@@ -60,6 +61,8 @@ public abstract class CQLTester
 
     private String currentTable;
 
+    private final Set<String> currentTypes = new HashSet<>();
+
     @BeforeClass
     public static void setUpClass() throws Throwable
     {
@@ -132,6 +135,13 @@ public abstract class CQLTester
         schemaChange(fullQuery);
     }
 
+    protected void createIndex(String query)
+    {
+        String fullQuery = String.format(query, KEYSPACE + "." + currentTable);
+        logger.info(fullQuery);
+        schemaChange(fullQuery);
+    }
+
     private static void schemaChange(String query)
     {
         try
@@ -466,6 +476,23 @@ public abstract class CQLTester
         return Arrays.asList(values);
     }
 
+    protected Object set(Object...values)
+    {
+        return ImmutableSet.copyOf(values);
+    }
+
+    protected Object map(Object...values)
+    {
+        if (values.length % 2 != 0)
+            throw new IllegalArgumentException();
+
+        int size = values.length / 2;
+        Map m = new HashMap(size);
+        for (int i = 0; i < size; i++)
+            m.put(values[2 * i], values[(2 * i) + 1]);
+        return m;
+    }
+
     // Attempt to find an AbstracType from a value (for serialization/printing sake).
     // Will work as long as we use types we know of, which is good enough for testing
     private static AbstractType typeFor(Object value)
@@ -495,6 +522,31 @@ public abstract class CQLTester
             return ListType.getInstance(elt);
         }
 
+        if (value instanceof Set)
+        {
+            Set s = (Set)value;
+            AbstractType elt = s.isEmpty() ? BytesType.instance : typeFor(s.iterator().next());
+            return SetType.getInstance(elt);
+        }
+
+        if (value instanceof Map)
+        {
+            Map m = (Map)value;
+            AbstractType keys, values;
+            if (m.isEmpty())
+            {
+                keys = BytesType.instance;
+                values = BytesType.instance;
+            }
+            else
+            {
+                Map.Entry entry = (Map.Entry)m.entrySet().iterator().next();
+                keys = typeFor(entry.getKey());
+                values = typeFor(entry.getValue());
+            }
+            return MapType.getInstance(keys, values);
+        }
+
         throw new IllegalArgumentException("Unsupported value type (value is " + value + ")");
     }
 

http://git-wip-us.apache.org/repos/asf/cassandra/blob/0c6fad4a/test/unit/org/apache/cassandra/cql3/ContainsRelationTest.java
----------------------------------------------------------------------
diff --git a/test/unit/org/apache/cassandra/cql3/ContainsRelationTest.java b/test/unit/org/apache/cassandra/cql3/ContainsRelationTest.java
index eae9b9f..0c6cfe1 100644
--- a/test/unit/org/apache/cassandra/cql3/ContainsRelationTest.java
+++ b/test/unit/org/apache/cassandra/cql3/ContainsRelationTest.java
@@ -17,64 +17,82 @@
  */
 package org.apache.cassandra.cql3;
 
-import static com.google.common.collect.Lists.newArrayList;
-import static com.google.common.collect.Sets.newHashSet;
-
 import org.junit.Test;
 
-import com.google.common.collect.ImmutableMap;
-
 public class ContainsRelationTest extends CQLTester
 {
     @Test
-    public void testSetContains() throws Throwable 
+    public void testSetContains() throws Throwable
     {
-        createTable("CREATE TABLE %s (account text, id int, categories set<text>, PRIMARY KEY (account, id));");
-        execute("CREATE INDEX cat_index_set ON %s(categories);");
-        execute("INSERT INTO %s (account, id , categories) VALUES ('test', 5, {'lmn'});");
-        
-        assertEmpty(execute("SELECT * FROM %s WHERE account = 'xyz' AND categories CONTAINS 'lmn';"));
-        
-        assertRows(execute("SELECT * FROM %s WHERE categories CONTAINS 'lmn';"), row("test", 5, newHashSet("lmn")));
-        assertRows(execute("SELECT * FROM %s WHERE account = 'test' AND categories CONTAINS 'lmn';"), row("test", 5, newHashSet("lmn")));
+        createTable("CREATE TABLE %s (account text, id int, categories set<text>, PRIMARY KEY (account, id))");
+        createIndex("CREATE INDEX ON %s(categories)");
+
+        execute("INSERT INTO %s (account, id , categories) VALUES (?, ?, ?)", "test", 5, set("lmn"));
+
+        assertEmpty(execute("SELECT * FROM %s WHERE account = ? AND categories CONTAINS ?", "xyz", "lmn"));
+
+        assertRows(execute("SELECT * FROM %s WHERE categories CONTAINS ?", "lmn"),
+            row("test", 5, set("lmn"))
+        );
+
+        assertRows(execute("SELECT * FROM %s WHERE account = ? AND categories CONTAINS ?", "test", "lmn"),
+            row("test", 5, set("lmn"))
+        );
     }
-    
+
     @Test
-    public void testListContains() throws Throwable 
+    public void testListContains() throws Throwable
     {
-        createTable("CREATE TABLE %s (account text, id int, categories list<text>, PRIMARY KEY (account, id));");
-        execute("CREATE INDEX cat_index_list ON %s(categories);");
-        execute("INSERT INTO %s (account, id , categories) VALUES ('test', 5, ['lmn']);");
-        
-        assertEmpty(execute("SELECT * FROM %s WHERE account = 'xyz' AND categories CONTAINS 'lmn';"));
-        
-        assertRows(execute("SELECT * FROM %s WHERE account = 'test' AND categories CONTAINS 'lmn';"), row("test", 5, newArrayList("lmn")));
-        assertRows(execute("SELECT * FROM %s WHERE categories CONTAINS 'lmn';"), row("test", 5, newArrayList("lmn")));
+        createTable("CREATE TABLE %s (account text, id int, categories list<text>, PRIMARY KEY (account, id))");
+        createIndex("CREATE INDEX ON %s(categories)");
+
+        execute("INSERT INTO %s (account, id , categories) VALUES (?, ?, ?)", "test", 5, list("lmn"));
+
+        assertEmpty(execute("SELECT * FROM %s WHERE account = ? AND categories CONTAINS ?", "xyz", "lmn"));
+
+        assertRows(execute("SELECT * FROM %s WHERE account = ? AND categories CONTAINS ?;", "test", "lmn"),
+            row("test", 5, list("lmn"))
+        );
+
+        assertRows(execute("SELECT * FROM %s WHERE categories CONTAINS ?", "lmn"),
+            row("test", 5, list("lmn"))
+        );
     }
-    
+
     @Test
-    public void testMapKeyContains() throws Throwable 
+    public void testMapKeyContains() throws Throwable
     {
-        createTable("CREATE TABLE %s (account text, id int, categories map<text,text>, PRIMARY KEY (account, id));");
-        execute("CREATE INDEX cat_index_map_key ON  %s(keys(categories));");
-        execute("INSERT INTO %s (account, id , categories) VALUES ('test', 5, {'lmn':'foo'});");
-        
-        assertEmpty(execute("SELECT * FROM %s WHERE account = 'xyz' AND categories CONTAINS KEY 'lmn';"));
-        
-        assertRows(execute("SELECT * FROM %s WHERE account = 'test' AND categories CONTAINS KEY 'lmn';"), row("test", 5, ImmutableMap.of("lmn", "foo")));
-        assertRows(execute("SELECT * FROM %s WHERE categories CONTAINS KEY 'lmn';"), row("test", 5, ImmutableMap.of("lmn", "foo")));
+        createTable("CREATE TABLE %s (account text, id int, categories map<text,text>, PRIMARY KEY (account, id))");
+        createIndex("CREATE INDEX ON %s(keys(categories))");
+
+        execute("INSERT INTO %s (account, id , categories) VALUES (?, ?, ?)", "test", 5, map("lmn", "foo"));
+
+        assertEmpty(execute("SELECT * FROM %s WHERE account = ? AND categories CONTAINS KEY ?", "xyz", "lmn"));
+
+        assertRows(execute("SELECT * FROM %s WHERE account = ? AND categories CONTAINS KEY ?", "test", "lmn"),
+            row("test", 5, map("lmn", "foo"))
+        );
+        assertRows(execute("SELECT * FROM %s WHERE categories CONTAINS KEY ?", "lmn"),
+            row("test", 5, map("lmn", "foo"))
+        );
     }
-    
+
     @Test
-    public void testMapValueContains() throws Throwable 
+    public void testMapValueContains() throws Throwable
     {
-        createTable("CREATE TABLE %s (account text, id int, categories map<text,text>, PRIMARY KEY (account, id));");
-        execute("CREATE INDEX cat_index_map_value ON  %s(categories);");
-        execute("INSERT INTO %s (account, id , categories) VALUES ('test', 5, {'lmn':'foo'});");
-        
-        assertEmpty(execute("SELECT * FROM %s WHERE account = 'xyz' AND categories CONTAINS 'foo';"));
-        
-        assertRows(execute("SELECT * FROM %s WHERE account = 'test' AND categories CONTAINS 'foo';"), row("test", 5, ImmutableMap.of("lmn", "foo")));
-        assertRows(execute("SELECT * FROM %s WHERE categories CONTAINS 'foo';"), row("test", 5, ImmutableMap.of("lmn", "foo")));
+        createTable("CREATE TABLE %s (account text, id int, categories map<text,text>, PRIMARY KEY (account, id))");
+        createIndex("CREATE INDEX ON %s(categories)");
+
+        execute("INSERT INTO %s (account, id , categories) VALUES (?, ?, ?)", "test", 5, map("lmn", "foo"));
+
+        assertEmpty(execute("SELECT * FROM %s WHERE account = ? AND categories CONTAINS ?", "xyz", "foo"));
+
+        assertRows(execute("SELECT * FROM %s WHERE account = ? AND categories CONTAINS ?", "test", "foo"),
+            row("test", 5, map("lmn", "foo"))
+        );
+
+        assertRows(execute("SELECT * FROM %s WHERE categories CONTAINS ?", "foo"),
+            row("test", 5, map("lmn", "foo"))
+        );
     }
 }


[3/4] git commit: Merge branch 'cassandra-2.1.0' into cassandra-2.1

Posted by sl...@apache.org.
Merge branch 'cassandra-2.1.0' into cassandra-2.1

Conflicts:
	CHANGES.txt


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

Branch: refs/heads/trunk
Commit: 59a8504c34b361e88ed10964c150272edcc91ff5
Parents: 0b54c4e 8d87e0e
Author: Sylvain Lebresne <sy...@datastax.com>
Authored: Mon Jul 7 18:06:04 2014 +0200
Committer: Sylvain Lebresne <sy...@datastax.com>
Committed: Mon Jul 7 18:06:04 2014 +0200

----------------------------------------------------------------------
 CHANGES.txt                                     |   4 +-
 .../org/apache/cassandra/cql3/Constants.java    |   8 +-
 .../org/apache/cassandra/cql3/UserTypes.java    |  11 ++
 .../cassandra/cql3/VariableSpecifications.java  |   6 ++
 .../cql3/statements/SelectStatement.java        |   1 +
 .../org/apache/cassandra/transport/Message.java |  51 +++++----
 .../org/apache/cassandra/cql3/CQLTester.java    |  82 ++++++++++++--
 .../cassandra/cql3/ContainsRelationTest.java    | 106 +++++++++++--------
 .../apache/cassandra/cql3/UserTypesTest.java    |  33 ++++++
 9 files changed, 227 insertions(+), 75 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cassandra/blob/59a8504c/CHANGES.txt
----------------------------------------------------------------------
diff --cc CHANGES.txt
index b93005e,491ad6d..682f599
--- a/CHANGES.txt
+++ b/CHANGES.txt
@@@ -1,10 -1,4 +1,10 @@@
 +2.1.1
 + * Improve schema merge performance (CASSANDRA-7444)
 + * Fix NPE when unknown prepared statement ID is used (CASSANDRA-7454)
 + * Adjust MT depth based on # of partition validating (CASSANDRA-5263)
 + * Optimise NativeCell comparisons (CASSANDRA-6755)
 +
- 2.1.0
+ 2.1.0-rc3
   * Fix ClassCastException processing expired messages (CASSANDRA-7496)
   * Fix prepared marker for collections inside UDT (CASSANDRA-7472)
   * Remove left-over populate_io_cache_on_flush and replicate_on_write


[4/4] git commit: Merge branch 'cassandra-2.1' into trunk

Posted by sl...@apache.org.
Merge branch 'cassandra-2.1' into trunk


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

Branch: refs/heads/trunk
Commit: e28cc6354e3ac45edf4c6fafea4599720e2dab97
Parents: d13a996 59a8504
Author: Sylvain Lebresne <sy...@datastax.com>
Authored: Mon Jul 7 18:06:31 2014 +0200
Committer: Sylvain Lebresne <sy...@datastax.com>
Committed: Mon Jul 7 18:06:31 2014 +0200

----------------------------------------------------------------------
 CHANGES.txt                                     |   4 +-
 .../org/apache/cassandra/cql3/Constants.java    |   8 +-
 .../org/apache/cassandra/cql3/UserTypes.java    |  11 ++
 .../cassandra/cql3/VariableSpecifications.java  |   6 ++
 .../cql3/statements/SelectStatement.java        |   1 +
 .../org/apache/cassandra/transport/Message.java |  51 +++++----
 .../org/apache/cassandra/cql3/CQLTester.java    |  82 ++++++++++++--
 .../cassandra/cql3/ContainsRelationTest.java    | 106 +++++++++++--------
 .../apache/cassandra/cql3/UserTypesTest.java    |  33 ++++++
 9 files changed, 227 insertions(+), 75 deletions(-)
----------------------------------------------------------------------


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

http://git-wip-us.apache.org/repos/asf/cassandra/blob/e28cc635/src/java/org/apache/cassandra/cql3/Constants.java
----------------------------------------------------------------------

http://git-wip-us.apache.org/repos/asf/cassandra/blob/e28cc635/test/unit/org/apache/cassandra/cql3/ContainsRelationTest.java
----------------------------------------------------------------------
diff --cc test/unit/org/apache/cassandra/cql3/ContainsRelationTest.java
index 7b9ef91,0c6cfe1..508cc4a
--- a/test/unit/org/apache/cassandra/cql3/ContainsRelationTest.java
+++ b/test/unit/org/apache/cassandra/cql3/ContainsRelationTest.java
@@@ -1,12 -1,24 +1,7 @@@
 -/*
 - * 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;
  
- import static com.google.common.collect.Lists.newArrayList;
- import static com.google.common.collect.Sets.newHashSet;
- 
  import org.junit.Test;
  
- import com.google.common.collect.ImmutableMap;
- 
  public class ContainsRelationTest extends CQLTester
  {
      @Test


[2/4] git commit: Properly reject unknown UDT fields

Posted by sl...@apache.org.
Properly reject unknown UDT fields

patch by slebresne; reviewed by tjake for CASSANDRA-7484


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

Branch: refs/heads/trunk
Commit: 8d87e0e25e7252926bbe8b671bd86262ba7bc246
Parents: 0c6fad4
Author: Sylvain Lebresne <sy...@datastax.com>
Authored: Mon Jul 7 17:50:26 2014 +0200
Committer: Sylvain Lebresne <sy...@datastax.com>
Committed: Mon Jul 7 17:50:26 2014 +0200

----------------------------------------------------------------------
 CHANGES.txt                                     |  1 +
 .../org/apache/cassandra/cql3/Constants.java    |  8 ++-
 .../org/apache/cassandra/cql3/UserTypes.java    | 11 +++++
 .../cassandra/cql3/VariableSpecifications.java  |  6 +++
 .../org/apache/cassandra/transport/Message.java | 51 +++++++++++---------
 .../org/apache/cassandra/cql3/CQLTester.java    | 30 +++++++++---
 .../apache/cassandra/cql3/UserTypesTest.java    | 33 +++++++++++++
 7 files changed, 110 insertions(+), 30 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cassandra/blob/8d87e0e2/CHANGES.txt
----------------------------------------------------------------------
diff --git a/CHANGES.txt b/CHANGES.txt
index 095624d..491ad6d 100644
--- a/CHANGES.txt
+++ b/CHANGES.txt
@@ -8,6 +8,7 @@
    commit log segments (CASSANDRA-7437)
  * Remove left-over rows_per_partition_to_cache (CASSANDRA-7493)
  * Fix error when CONTAINS is used with a bind marker (CASSANDRA-7502)
+ * Properly reject unknown UDT field (CASSANDRA-7484)
 Merged from 2.0:
  * Fix CC#collectTimeOrderedData() tombstone optimisations (CASSANDRA-7394)
  * Support DISTINCT for static columns and fix behaviour when DISTINC is

http://git-wip-us.apache.org/repos/asf/cassandra/blob/8d87e0e2/src/java/org/apache/cassandra/cql3/Constants.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/cql3/Constants.java b/src/java/org/apache/cassandra/cql3/Constants.java
index 58b11dd..48f62dc 100644
--- a/src/java/org/apache/cassandra/cql3/Constants.java
+++ b/src/java/org/apache/cassandra/cql3/Constants.java
@@ -58,6 +58,12 @@ public abstract class Constants
                 // We return null because that makes life easier for collections
                 return null;
             }
+
+            @Override
+            public String toString()
+            {
+                return "null";
+            }
         };
 
         public Term prepare(String keyspace, ColumnSpecification receiver) throws InvalidRequestException
@@ -76,7 +82,7 @@ public abstract class Constants
         @Override
         public String toString()
         {
-            return null;
+            return "null";
         }
     };
 

http://git-wip-us.apache.org/repos/asf/cassandra/blob/8d87e0e2/src/java/org/apache/cassandra/cql3/UserTypes.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/cql3/UserTypes.java b/src/java/org/apache/cassandra/cql3/UserTypes.java
index 876de2a..bb6e7d0 100644
--- a/src/java/org/apache/cassandra/cql3/UserTypes.java
+++ b/src/java/org/apache/cassandra/cql3/UserTypes.java
@@ -57,12 +57,15 @@ public abstract class UserTypes
             UserType ut = (UserType)receiver.type;
             boolean allTerminal = true;
             List<Term> values = new ArrayList<>(entries.size());
+            int foundValues = 0;
             for (int i = 0; i < ut.size(); i++)
             {
                 ColumnIdentifier field = new ColumnIdentifier(ut.fieldName(i), UTF8Type.instance);
                 Term.Raw raw = entries.get(field);
                 if (raw == null)
                     raw = Constants.NULL_LITERAL;
+                else
+                    ++foundValues;
                 Term value = raw.prepare(keyspace, fieldSpecOf(receiver, i));
 
                 if (value instanceof Term.NonTerminal)
@@ -70,6 +73,14 @@ public abstract class UserTypes
 
                 values.add(value);
             }
+            if (foundValues != entries.size())
+            {
+                // We had some field that are not part of the type
+                for (ColumnIdentifier id : entries.keySet())
+                    if (!ut.fieldNames().contains(id.bytes))
+                        throw new InvalidRequestException(String.format("Unknown field '%s' in value of user defined type %s", id, ut.getNameAsString()));
+            }
+
             DelayedValue value = new DelayedValue(((UserType)receiver.type), values);
             return allTerminal ? value.bind(QueryOptions.DEFAULT) : value;
         }

http://git-wip-us.apache.org/repos/asf/cassandra/blob/8d87e0e2/src/java/org/apache/cassandra/cql3/VariableSpecifications.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/cql3/VariableSpecifications.java b/src/java/org/apache/cassandra/cql3/VariableSpecifications.java
index ecdba6f..ef78619 100644
--- a/src/java/org/apache/cassandra/cql3/VariableSpecifications.java
+++ b/src/java/org/apache/cassandra/cql3/VariableSpecifications.java
@@ -49,4 +49,10 @@ public class VariableSpecifications
             spec = new ColumnSpecification(spec.ksName, spec.cfName, name, spec.type);
         specs[bindIndex] = spec;
     }
+
+    @Override
+    public String toString()
+    {
+        return Arrays.toString(specs);
+    }
 }

http://git-wip-us.apache.org/repos/asf/cassandra/blob/8d87e0e2/src/java/org/apache/cassandra/transport/Message.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/transport/Message.java b/src/java/org/apache/cassandra/transport/Message.java
index eea86e5..b02b176 100644
--- a/src/java/org/apache/cassandra/transport/Message.java
+++ b/src/java/org/apache/cassandra/transport/Message.java
@@ -270,41 +270,48 @@ public abstract class Message
             EnumSet<Frame.Header.Flag> flags = EnumSet.noneOf(Frame.Header.Flag.class);
 
             Codec<Message> codec = (Codec<Message>)message.type.codec;
-            int messageSize = codec.encodedSize(message, version);
-            ByteBuf body;
-            if (message instanceof Response)
+            try
             {
-                UUID tracingId = ((Response)message).getTracingId();
-                if (tracingId != null)
+                int messageSize = codec.encodedSize(message, version);
+                ByteBuf body;
+                if (message instanceof Response)
                 {
-                    body = CBUtil.allocator.buffer(CBUtil.sizeOfUUID(tracingId) + messageSize);
-                    CBUtil.writeUUID(tracingId, body);
-                    flags.add(Frame.Header.Flag.TRACING);
+                    UUID tracingId = ((Response)message).getTracingId();
+                    if (tracingId != null)
+                    {
+                        body = CBUtil.allocator.buffer(CBUtil.sizeOfUUID(tracingId) + messageSize);
+                        CBUtil.writeUUID(tracingId, body);
+                        flags.add(Frame.Header.Flag.TRACING);
+                    }
+                    else
+                    {
+                        body = CBUtil.allocator.buffer(messageSize);
+                    }
                 }
                 else
                 {
+                    assert message instanceof Request;
                     body = CBUtil.allocator.buffer(messageSize);
+                    if (((Request)message).isTracingRequested())
+                        flags.add(Frame.Header.Flag.TRACING);
                 }
-            }
-            else
-            {
-                assert message instanceof Request;
-                body = CBUtil.allocator.buffer(messageSize);
-                if (((Request)message).isTracingRequested())
-                    flags.add(Frame.Header.Flag.TRACING);
-            }
 
-            try
-            {
-                codec.encode(message, body, version);
+                try
+                {
+                    codec.encode(message, body, version);
+                }
+                catch (Throwable e)
+                {
+                    body.release();
+                    throw e;
+                }
+
+                results.add(Frame.create(message.type, message.getStreamId(), version, flags, body));
             }
             catch (Throwable e)
             {
-                body.release();
                 throw ErrorMessage.wrap(e, message.getStreamId());
             }
-
-            results.add(Frame.create(message.type, message.getStreamId(), version, flags, body));
         }
     }
 

http://git-wip-us.apache.org/repos/asf/cassandra/blob/8d87e0e2/test/unit/org/apache/cassandra/cql3/CQLTester.java
----------------------------------------------------------------------
diff --git a/test/unit/org/apache/cassandra/cql3/CQLTester.java b/test/unit/org/apache/cassandra/cql3/CQLTester.java
index b861d49..38aff2b 100644
--- a/test/unit/org/apache/cassandra/cql3/CQLTester.java
+++ b/test/unit/org/apache/cassandra/cql3/CQLTester.java
@@ -60,6 +60,7 @@ public abstract class CQLTester
     }
 
     private String currentTable;
+    private final Set<String> currentTypes = new HashSet<>();
 
     private final Set<String> currentTypes = new HashSet<>();
 
@@ -80,8 +81,10 @@ public abstract class CQLTester
         if (currentTable == null)
             return;
 
-        final String toDrop = currentTable;
+        final String tableToDrop = currentTable;
+        final Set<String> typesToDrop = currentTypes.isEmpty() ? Collections.emptySet() : new HashSet(currentTypes);
         currentTable = null;
+        currentTypes.clear();
 
         // We want to clean up after the test, but dropping a table is rather long so just do that asynchronously
         StorageService.tasks.execute(new Runnable()
@@ -90,7 +93,10 @@ public abstract class CQLTester
             {
                 try
                 {
-                    schemaChange(String.format("DROP TABLE %s.%s", KEYSPACE, toDrop));
+                    schemaChange(String.format("DROP TABLE %s.%s", KEYSPACE, tableToDrop));
+
+                    for (String typeName : typesToDrop)
+                        schemaChange(String.format("DROP TYPE %s.%s", KEYSPACE, typeName));
 
                     // Dropping doesn't delete the sstables. It's not a huge deal but it's cleaner to cleanup after us
                     // Thas said, we shouldn't delete blindly before the SSTableDeletingTask for the table we drop
@@ -99,15 +105,15 @@ public abstract class CQLTester
 
                     final CountDownLatch latch = new CountDownLatch(1);
                     StorageService.tasks.execute(new Runnable()
-                        {
-                            public void run()
                     {
-                        latch.countDown();
-                    }
+                            public void run()
+                            {
+                                latch.countDown();
+                            }
                     });
                     latch.await(2, TimeUnit.SECONDS);
 
-                    removeAllSSTables(KEYSPACE, toDrop);
+                    removeAllSSTables(KEYSPACE, tableToDrop);
                 }
                 catch (Exception e)
                 {
@@ -127,6 +133,16 @@ public abstract class CQLTester
         }
     }
 
+    protected String createType(String query)
+    {
+        String typeName = "type_" + seqNumber.getAndIncrement();
+        String fullQuery = String.format(query, KEYSPACE + "." + typeName);
+        currentTypes.add(typeName);
+        logger.info(fullQuery);
+        schemaChange(fullQuery);
+        return typeName;
+    }
+
     protected void createTable(String query)
     {
         currentTable = "table_" + seqNumber.getAndIncrement();

http://git-wip-us.apache.org/repos/asf/cassandra/blob/8d87e0e2/test/unit/org/apache/cassandra/cql3/UserTypesTest.java
----------------------------------------------------------------------
diff --git a/test/unit/org/apache/cassandra/cql3/UserTypesTest.java b/test/unit/org/apache/cassandra/cql3/UserTypesTest.java
new file mode 100644
index 0000000..a8fd7a4
--- /dev/null
+++ b/test/unit/org/apache/cassandra/cql3/UserTypesTest.java
@@ -0,0 +1,33 @@
+/*
+ * 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;
+
+import org.junit.Test;
+
+public class UserTypesTest extends CQLTester
+{
+    @Test
+    public void testInvalidField() throws Throwable
+    {
+        String myType = createType("CREATE TYPE %s (f int)");
+        createTable("CREATE TABLE %s (k int PRIMARY KEY, v " + myType + ")");
+
+        // 's' is not a field of myType
+        assertInvalid("INSERT INTO %s (k, v) VALUES (?, {s : ?})", 0, 1);
+    }
+}