cassandra-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From tylerho...@apache.org
Subject [1/8] cassandra git commit: Fix mixed single and multi-column relation support
Date Thu, 05 Mar 2015 18:35:08 GMT
Repository: cassandra
Updated Branches:
  refs/heads/trunk 258e59fcf -> 71778eec2


http://git-wip-us.apache.org/repos/asf/cassandra/blob/90a012a1/test/unit/org/apache/cassandra/cql3/statements/SelectStatementTest.java
----------------------------------------------------------------------
diff --git a/test/unit/org/apache/cassandra/cql3/statements/SelectStatementTest.java b/test/unit/org/apache/cassandra/cql3/statements/SelectStatementTest.java
new file mode 100644
index 0000000..1a66002
--- /dev/null
+++ b/test/unit/org/apache/cassandra/cql3/statements/SelectStatementTest.java
@@ -0,0 +1,973 @@
+/*
+ * 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.statements;
+
+import java.nio.ByteBuffer;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+import org.junit.Test;
+
+import org.apache.cassandra.config.CFMetaData;
+import org.apache.cassandra.config.ColumnDefinition;
+import org.apache.cassandra.cql3.*;
+import org.apache.cassandra.cql3.CFDefinition.Name;
+import org.apache.cassandra.db.ColumnFamilyType;
+import org.apache.cassandra.db.marshal.AbstractType;
+import org.apache.cassandra.db.marshal.CompositeType;
+import org.apache.cassandra.db.marshal.Int32Type;
+import org.apache.cassandra.exceptions.ConfigurationException;
+import org.apache.cassandra.exceptions.InvalidRequestException;
+import org.apache.cassandra.utils.ByteBufferUtil;
+
+import static org.junit.Assert.assertArrayEquals;
+
+import static java.util.Arrays.asList;
+import static org.junit.Assert.assertEquals;
+
+public class SelectStatementTest
+{
+    @Test
+    public void testBuildBoundWithNoRestrictions() throws Exception
+    {
+        Restriction[] restrictions = new Restriction[2];
+        CFDefinition cfDef = createCFDefinition(restrictions.length);
+
+        List<ByteBuffer> bounds = executeBuildBound(cfDef, restrictions, Bound.START);
+        assertEquals(1, bounds.size());
+        assertComposite(cfDef, bounds.get(0));
+
+        bounds = executeBuildBound(cfDef, restrictions, Bound.END);
+        assertEquals(1, bounds.size());
+        assertComposite(cfDef, bounds.get(0));
+    }
+
+    /**
+     * Test 'clustering_0 = 1' with only one clustering column
+     */
+    @Test
+    public void testBuildBoundWithOneEqRestrictionsAndOneClusteringColumn() throws Exception
+    {
+        ByteBuffer clustering_0 = ByteBufferUtil.bytes(1);
+        SingleColumnRestriction.EQ eq = new SingleColumnRestriction.EQ(toTerm(clustering_0),
false);
+        Restriction[] restrictions = new Restriction[] { eq };
+        CFDefinition cfDef = createCFDefinition(restrictions.length);
+
+        List<ByteBuffer> bounds = executeBuildBound(cfDef, restrictions, Bound.START);
+        assertEquals(1, bounds.size());
+        assertComposite(cfDef, bounds.get(0), clustering_0);
+
+        bounds = executeBuildBound(cfDef, restrictions, Bound.END);
+        assertEquals(1, bounds.size());
+        assertComposite(cfDef, bounds.get(0), clustering_0);
+    }
+
+    /**
+     * Test 'clustering_1 = 1' with 2 clustering columns
+     */
+    @Test
+    public void testBuildBoundWithOneEqRestrictionsAndTwoClusteringColumns() throws Exception
+    {
+        ByteBuffer clustering_0 = ByteBufferUtil.bytes(1);
+        SingleColumnRestriction.EQ eq = new SingleColumnRestriction.EQ(toTerm(clustering_0),
false);
+        Restriction[] restrictions = new Restriction[] { eq, null };
+        CFDefinition cfDef = createCFDefinition(restrictions.length);
+
+        List<ByteBuffer> bounds = executeBuildBound(cfDef, restrictions, Bound.START);
+        assertEquals(1, bounds.size());
+        assertComposite(cfDef, bounds.get(0), clustering_0);
+
+        bounds = executeBuildBound(cfDef,restrictions, Bound.END);
+        assertEquals(1, bounds.size());
+        assertEndOfRangeComposite(cfDef, bounds.get(0), clustering_0);
+    }
+
+    /**
+     * Test 'clustering_0 IN (1, 2, 3)' with only one clustering column
+     */
+    @Test
+    public void testBuildBoundWithOneInRestrictionsAndOneClusteringColumn() throws Exception
+    {
+        ByteBuffer value1 = ByteBufferUtil.bytes(1);
+        ByteBuffer value2 = ByteBufferUtil.bytes(2);
+        ByteBuffer value3 = ByteBufferUtil.bytes(3);
+        SingleColumnRestriction.IN in = new SingleColumnRestriction.InWithValues(toTerms(value1,
value2, value3));
+        Restriction[] restrictions = new Restriction[] { in };
+        CFDefinition cfDef = createCFDefinition(restrictions.length);
+
+        List<ByteBuffer> bounds = executeBuildBound(cfDef,restrictions, Bound.START);
+        assertEquals(3, bounds.size());
+        assertComposite(cfDef, bounds.get(0), value1);
+        assertComposite(cfDef, bounds.get(1), value2);
+        assertComposite(cfDef, bounds.get(2), value3);
+
+        bounds = executeBuildBound(cfDef,restrictions, Bound.END);
+        assertEquals(3, bounds.size());
+        assertComposite(cfDef, bounds.get(0), value1);
+        assertComposite(cfDef, bounds.get(1), value2);
+        assertComposite(cfDef, bounds.get(2), value3);
+    }
+
+    /**
+     * Test slice restriction (e.g 'clustering_0 > 1') with only one clustering column
+     */
+    @Test
+    public void testBuildBoundWithSliceRestrictionsAndOneClusteringColumn() throws Exception
+    {
+        ByteBuffer value1 = ByteBufferUtil.bytes(1);
+        ByteBuffer value2 = ByteBufferUtil.bytes(2);
+
+        SingleColumnRestriction.Slice slice = new SingleColumnRestriction.Slice(false);
+        slice.setBound(Relation.Type.GT, toTerm(value1));
+        Restriction[] restrictions = new Restriction[] { slice };
+        CFDefinition cfDef = createCFDefinition(restrictions.length);
+
+        List<ByteBuffer> bounds = executeBuildBound(cfDef,restrictions, Bound.START);
+        assertEquals(1, bounds.size());
+        assertForRelationComposite(cfDef, bounds.get(0), Relation.Type.GT, value1);
+
+        bounds = executeBuildBound(cfDef,restrictions, Bound.END);
+        assertEquals(1, bounds.size());
+        assertComposite(cfDef, bounds.get(0));
+
+        slice = new SingleColumnRestriction.Slice(false);
+        slice.setBound(Relation.Type.GTE, toTerm(value1));
+        restrictions = new Restriction[] { slice };
+
+        bounds = executeBuildBound(cfDef,restrictions, Bound.START);
+        assertEquals(1, bounds.size());
+        assertForRelationComposite(cfDef, bounds.get(0), Relation.Type.GTE, value1);
+
+        bounds = executeBuildBound(cfDef,restrictions, Bound.END);
+        assertEquals(1, bounds.size());
+        assertComposite(cfDef, bounds.get(0));
+
+        slice = new SingleColumnRestriction.Slice(false);
+        slice.setBound(Relation.Type.LTE, toTerm(value1));
+        restrictions = new Restriction[] { slice };
+
+        bounds = executeBuildBound(cfDef,restrictions, Bound.START);
+        assertEquals(1, bounds.size());
+        assertComposite(cfDef, bounds.get(0));
+
+        bounds = executeBuildBound(cfDef,restrictions, Bound.END);
+        assertEquals(1, bounds.size());
+        assertForRelationComposite(cfDef, bounds.get(0), Relation.Type.LTE, value1);
+
+        slice = new SingleColumnRestriction.Slice(false);
+        slice.setBound(Relation.Type.LT, toTerm(value1));
+        restrictions = new Restriction[] { slice };
+
+        bounds = executeBuildBound(cfDef,restrictions, Bound.START);
+        assertEquals(1, bounds.size());
+        assertComposite(cfDef, bounds.get(0));
+
+        bounds = executeBuildBound(cfDef,restrictions, Bound.END);
+        assertEquals(1, bounds.size());
+        assertForRelationComposite(cfDef, bounds.get(0), Relation.Type.LT, value1);
+
+        slice = new SingleColumnRestriction.Slice(false);
+        slice.setBound(Relation.Type.GT, toTerm(value1));
+        slice.setBound(Relation.Type.LT, toTerm(value2));
+        restrictions = new Restriction[] { slice };
+
+        bounds = executeBuildBound(cfDef,restrictions, Bound.START);
+        assertEquals(1, bounds.size());
+        assertForRelationComposite(cfDef, bounds.get(0), Relation.Type.GT, value1);
+
+        bounds = executeBuildBound(cfDef,restrictions, Bound.END);
+        assertEquals(1, bounds.size());
+        assertForRelationComposite(cfDef, bounds.get(0), Relation.Type.LT, value2);
+
+        slice = new SingleColumnRestriction.Slice(false);
+        slice.setBound(Relation.Type.GTE, toTerm(value1));
+        slice.setBound(Relation.Type.LTE, toTerm(value2));
+        restrictions = new Restriction[] { slice };
+
+        bounds = executeBuildBound(cfDef,restrictions, Bound.START);
+        assertEquals(1, bounds.size());
+        assertForRelationComposite(cfDef, bounds.get(0), Relation.Type.GTE, value1);
+
+        bounds = executeBuildBound(cfDef,restrictions, Bound.END);
+        assertEquals(1, bounds.size());
+        assertForRelationComposite(cfDef, bounds.get(0), Relation.Type.LTE, value2);
+    }
+//
+    /**
+     * Test 'clustering_0 = 1 AND clustering_1 IN (1, 2, 3)' with two clustering columns
+     */
+    @Test
+    public void testBuildBoundWithEqAndInRestrictions() throws Exception
+    {
+        ByteBuffer value1 = ByteBufferUtil.bytes(1);
+        ByteBuffer value2 = ByteBufferUtil.bytes(2);
+        ByteBuffer value3 = ByteBufferUtil.bytes(3);
+        SingleColumnRestriction.EQ eq = new SingleColumnRestriction.EQ(toTerm(value1), false);
+        SingleColumnRestriction.IN in = new SingleColumnRestriction.InWithValues(toTerms(value1,
value2, value3));
+        Restriction[] restrictions = new Restriction[] { eq, in };
+        CFDefinition cfDef = createCFDefinition(restrictions.length);
+
+        List<ByteBuffer> bounds = executeBuildBound(cfDef,restrictions, Bound.START);
+        assertEquals(3, bounds.size());
+        assertComposite(cfDef, bounds.get(0), value1, value1);
+        assertComposite(cfDef, bounds.get(1), value1, value2);
+        assertComposite(cfDef, bounds.get(2), value1, value3);
+
+        bounds = executeBuildBound(cfDef,restrictions, Bound.END);
+        assertEquals(3, bounds.size());
+        assertComposite(cfDef, bounds.get(0), value1, value1);
+        assertComposite(cfDef, bounds.get(1), value1, value2);
+        assertComposite(cfDef, bounds.get(2), value1, value3);
+    }
+
+    /**
+     * Test slice restriction (e.g 'clustering_0 > 1') with only one clustering column
+     */
+    @Test
+    public void testBuildBoundWithEqAndSliceRestrictions() throws Exception
+    {
+        ByteBuffer value1 = ByteBufferUtil.bytes(1);
+        ByteBuffer value2 = ByteBufferUtil.bytes(2);
+        ByteBuffer value3 = ByteBufferUtil.bytes(3);
+
+        SingleColumnRestriction.EQ eq = new SingleColumnRestriction.EQ(toTerm(value3), false);
+
+        SingleColumnRestriction.Slice slice = new SingleColumnRestriction.Slice(false);
+        slice.setBound(Relation.Type.GT, toTerm(value1));
+        Restriction[] restrictions = new Restriction[] { eq, slice };
+        CFDefinition cfDef = createCFDefinition(restrictions.length);
+
+        List<ByteBuffer> bounds = executeBuildBound(cfDef,restrictions, Bound.START);
+        assertEquals(1, bounds.size());
+        assertForRelationComposite(cfDef, bounds.get(0), Relation.Type.GT, value3, value1);
+
+        bounds = executeBuildBound(cfDef,restrictions, Bound.END);
+        assertEquals(1, bounds.size());
+        assertEndOfRangeComposite(cfDef, bounds.get(0), value3);
+
+        slice = new SingleColumnRestriction.Slice(false);
+        slice.setBound(Relation.Type.GTE, toTerm(value1));
+        restrictions = new Restriction[] { eq, slice };
+
+        bounds = executeBuildBound(cfDef,restrictions, Bound.START);
+        assertEquals(1, bounds.size());
+        assertForRelationComposite(cfDef, bounds.get(0), Relation.Type.GTE, value3, value1);
+
+        bounds = executeBuildBound(cfDef, restrictions, Bound.END);
+        assertEquals(1, bounds.size());
+        assertEndOfRangeComposite(cfDef, bounds.get(0), value3);
+
+        slice = new SingleColumnRestriction.Slice(false);
+        slice.setBound(Relation.Type.LTE, toTerm(value1));
+        restrictions = new Restriction[] { eq, slice };
+
+        bounds = executeBuildBound(cfDef, restrictions, Bound.START);
+        assertEquals(1, bounds.size());
+        assertComposite(cfDef, bounds.get(0), value3);
+
+        bounds = executeBuildBound(cfDef, restrictions, Bound.END);
+        assertEquals(1, bounds.size());
+        assertForRelationComposite(cfDef, bounds.get(0), Relation.Type.LTE, value3, value1);
+
+        slice = new SingleColumnRestriction.Slice(false);
+        slice.setBound(Relation.Type.LT, toTerm(value1));
+        restrictions = new Restriction[] { eq, slice };
+
+        bounds = executeBuildBound(cfDef, restrictions, Bound.START);
+        assertEquals(1, bounds.size());
+        assertComposite(cfDef, bounds.get(0), value3);
+
+        bounds = executeBuildBound(cfDef, restrictions, Bound.END);
+        assertEquals(1, bounds.size());
+        assertForRelationComposite(cfDef, bounds.get(0), Relation.Type.LT, value3, value1);
+
+        slice = new SingleColumnRestriction.Slice(false);
+        slice.setBound(Relation.Type.GT, toTerm(value1));
+        slice.setBound(Relation.Type.LT, toTerm(value2));
+        restrictions = new Restriction[] { eq, slice };
+
+        bounds = executeBuildBound(cfDef, restrictions, Bound.START);
+        assertEquals(1, bounds.size());
+        assertForRelationComposite(cfDef, bounds.get(0), Relation.Type.GT, value3, value1);
+
+        bounds = executeBuildBound(cfDef, restrictions, Bound.END);
+        assertEquals(1, bounds.size());
+        assertForRelationComposite(cfDef, bounds.get(0), Relation.Type.LT, value3, value2);
+
+        slice = new SingleColumnRestriction.Slice(false);
+        slice.setBound(Relation.Type.GTE, toTerm(value1));
+        slice.setBound(Relation.Type.LTE, toTerm(value2));
+        restrictions = new Restriction[] { eq, slice };
+
+        bounds = executeBuildBound(cfDef, restrictions, Bound.START);
+        assertEquals(1, bounds.size());
+        assertForRelationComposite(cfDef, bounds.get(0), Relation.Type.GTE, value3, value1);
+
+        bounds = executeBuildBound(cfDef, restrictions, Bound.END);
+        assertEquals(1, bounds.size());
+        assertForRelationComposite(cfDef, bounds.get(0), Relation.Type.LTE, value3, value2);
+    }
+
+    /**
+     * Test '(clustering_0, clustering_1) = (1, 2)' with two clustering column
+     */
+    @Test
+    public void testBuildBoundWithMultiEqRestrictions() throws Exception
+    {
+        ByteBuffer value1 = ByteBufferUtil.bytes(1);
+        ByteBuffer value2 = ByteBufferUtil.bytes(2);
+        MultiColumnRestriction.EQ eq = new MultiColumnRestriction.EQ(toMultiItemTerminal(value1,
value2), false);
+        Restriction[] restrictions = new Restriction[] { eq, eq };
+        CFDefinition cfDef = createCFDefinition(restrictions.length);
+
+        List<ByteBuffer> bounds = executeBuildBound(cfDef, restrictions, Bound.START);
+        assertEquals(1, bounds.size());
+        assertComposite(cfDef, bounds.get(0), value1, value2);
+
+        bounds = executeBuildBound(cfDef, restrictions, Bound.END);
+        assertEquals(1, bounds.size());
+        assertComposite(cfDef, bounds.get(0), value1, value2);
+    }
+
+    /**
+     * Test '(clustering_0, clustering_1) IN ((1, 2), (2, 3))' with two clustering column
+     */
+    @Test
+    public void testBuildBoundWithMultiInRestrictions() throws Exception
+    {
+        ByteBuffer value1 = ByteBufferUtil.bytes(1);
+        ByteBuffer value2 = ByteBufferUtil.bytes(2);
+        ByteBuffer value3 = ByteBufferUtil.bytes(3);
+        List<Term> terms = asList(toMultiItemTerminal(value1, value2), toMultiItemTerminal(value2,
value3));
+        MultiColumnRestriction.IN in = new MultiColumnRestriction.InWithValues(terms);
+        Restriction[] restrictions = new Restriction[] { in, in };
+        CFDefinition cfDef = createCFDefinition(restrictions.length);
+
+        List<ByteBuffer> bounds = executeBuildBound(cfDef, restrictions, Bound.START);
+        assertEquals(2, bounds.size());
+        assertComposite(cfDef, bounds.get(0), value1, value2);
+        assertComposite(cfDef, bounds.get(1), value2, value3);
+
+        bounds = executeBuildBound(cfDef, restrictions, Bound.END);
+        assertEquals(2, bounds.size());
+        assertComposite(cfDef, bounds.get(0), value1, value2);
+        assertComposite(cfDef, bounds.get(1), value2, value3);
+    }
+
+    /**
+     * Test multi-column slice restrictions (e.g '(clustering_0) > (1)') with only one
clustering column
+     */
+    @Test
+    public void testBuildBoundWithMultiSliceRestrictionsWithOneClusteringColumn() throws
Exception
+    {
+        ByteBuffer value1 = ByteBufferUtil.bytes(1);
+        ByteBuffer value2 = ByteBufferUtil.bytes(2);
+
+        MultiColumnRestriction.Slice slice = new MultiColumnRestriction.Slice(false);
+        slice.setBound(Relation.Type.GT, toMultiItemTerminal(value1));
+        Restriction[] restrictions = new Restriction[] { slice };
+        CFDefinition cfDef = createCFDefinition(restrictions.length);
+
+        List<ByteBuffer> bounds = executeBuildBound(cfDef, restrictions, Bound.START);
+        assertEquals(1, bounds.size());
+        assertForRelationComposite(cfDef, bounds.get(0), Relation.Type.GT, value1);
+
+        bounds = executeBuildBound(cfDef, restrictions, Bound.END);
+        assertEquals(1, bounds.size());
+        assertComposite(cfDef, bounds.get(0));
+
+        slice = new MultiColumnRestriction.Slice(false);
+        slice.setBound(Relation.Type.GTE, toMultiItemTerminal(value1));
+        restrictions = new Restriction[] { slice };
+
+        bounds = executeBuildBound(cfDef, restrictions, Bound.START);
+        assertEquals(1, bounds.size());
+        assertForRelationComposite(cfDef, bounds.get(0), Relation.Type.GTE, value1);
+
+        bounds = executeBuildBound(cfDef, restrictions, Bound.END);
+        assertEquals(1, bounds.size());
+        assertComposite(cfDef, bounds.get(0));
+
+        slice = new MultiColumnRestriction.Slice(false);
+        slice.setBound(Relation.Type.LTE, toMultiItemTerminal(value1));
+        restrictions = new Restriction[] { slice };
+
+        bounds = executeBuildBound(cfDef, restrictions, Bound.START);
+        assertEquals(1, bounds.size());
+        assertComposite(cfDef, bounds.get(0));
+
+        bounds = executeBuildBound(cfDef, restrictions, Bound.END);
+        assertEquals(1, bounds.size());
+        assertForRelationComposite(cfDef, bounds.get(0), Relation.Type.LTE, value1);
+
+        slice = new MultiColumnRestriction.Slice(false);
+        slice.setBound(Relation.Type.LT, toMultiItemTerminal(value1));
+        restrictions = new Restriction[] { slice };
+
+        bounds = executeBuildBound(cfDef, restrictions, Bound.START);
+        assertEquals(1, bounds.size());
+        assertComposite(cfDef, bounds.get(0));
+
+        bounds = executeBuildBound(cfDef, restrictions, Bound.END);
+        assertEquals(1, bounds.size());
+        assertForRelationComposite(cfDef, bounds.get(0), Relation.Type.LT, value1);
+
+        slice = new MultiColumnRestriction.Slice(false);
+        slice.setBound(Relation.Type.GT, toMultiItemTerminal(value1));
+        slice.setBound(Relation.Type.LT, toMultiItemTerminal(value2));
+        restrictions = new Restriction[] { slice };
+
+        bounds = executeBuildBound(cfDef, restrictions, Bound.START);
+        assertEquals(1, bounds.size());
+        assertForRelationComposite(cfDef, bounds.get(0), Relation.Type.GT, value1);
+
+        bounds = executeBuildBound(cfDef, restrictions, Bound.END);
+        assertEquals(1, bounds.size());
+        assertForRelationComposite(cfDef, bounds.get(0), Relation.Type.LT, value2);
+
+        slice = new MultiColumnRestriction.Slice(false);
+        slice.setBound(Relation.Type.GTE, toMultiItemTerminal(value1));
+        slice.setBound(Relation.Type.LTE, toMultiItemTerminal(value2));
+        restrictions = new Restriction[] { slice };
+
+        bounds = executeBuildBound(cfDef, restrictions, Bound.START);
+        assertEquals(1, bounds.size());
+        assertForRelationComposite(cfDef, bounds.get(0), Relation.Type.GTE, value1);
+
+        bounds = executeBuildBound(cfDef, restrictions, Bound.END);
+        assertEquals(1, bounds.size());
+        assertForRelationComposite(cfDef, bounds.get(0), Relation.Type.LTE, value2);
+    }
+
+    /**
+     * Test multi-column slice restrictions (e.g '(clustering_0, clustering_1) > (1, 2)')
with two clustering
+     * columns
+     */
+    @Test
+    public void testBuildBoundWithMultiSliceRestrictionsWithTwoClusteringColumn() throws
Exception
+    {
+        ByteBuffer value1 = ByteBufferUtil.bytes(1);
+        ByteBuffer value2 = ByteBufferUtil.bytes(2);
+
+        // (clustering_0, clustering1) > (1, 2)
+        MultiColumnRestriction.Slice slice = new MultiColumnRestriction.Slice(false);
+        slice.setBound(Relation.Type.GT, toMultiItemTerminal(value1, value2));
+        Restriction[] restrictions = new Restriction[] { slice, slice };
+        CFDefinition cfDef = createCFDefinition(restrictions.length);
+
+        List<ByteBuffer> bounds = executeBuildBound(cfDef, restrictions, Bound.START);
+        assertEquals(1, bounds.size());
+        assertForRelationComposite(cfDef, bounds.get(0), Relation.Type.GT, value1, value2);
+
+        bounds = executeBuildBound(cfDef, restrictions, Bound.END);
+        assertEquals(1, bounds.size());
+        assertComposite(cfDef, bounds.get(0));
+
+        // (clustering_0, clustering1) >= (1, 2)
+        slice = new MultiColumnRestriction.Slice(false);
+        slice.setBound(Relation.Type.GTE, toMultiItemTerminal(value1, value2));
+        restrictions = new Restriction[] { slice, slice };
+
+        bounds = executeBuildBound(cfDef, restrictions, Bound.START);
+        assertEquals(1, bounds.size());
+        assertForRelationComposite(cfDef, bounds.get(0), Relation.Type.GTE, value1, value2);
+
+        bounds = executeBuildBound(cfDef, restrictions, Bound.END);
+        assertEquals(1, bounds.size());
+        assertComposite(cfDef, bounds.get(0));
+
+        // (clustering_0, clustering1) <= (1, 2)
+        slice = new MultiColumnRestriction.Slice(false);
+        slice.setBound(Relation.Type.LTE, toMultiItemTerminal(value1, value2));
+        restrictions = new Restriction[] { slice, slice };
+
+        bounds = executeBuildBound(cfDef, restrictions, Bound.START);
+        assertEquals(1, bounds.size());
+        assertComposite(cfDef, bounds.get(0));
+
+        bounds = executeBuildBound(cfDef, restrictions, Bound.END);
+        assertEquals(1, bounds.size());
+        assertForRelationComposite(cfDef, bounds.get(0), Relation.Type.LTE, value1, value2);
+
+        // (clustering_0, clustering1) < (1, 2)
+        slice = new MultiColumnRestriction.Slice(false);
+        slice.setBound(Relation.Type.LT, toMultiItemTerminal(value1, value2));
+        restrictions = new Restriction[] { slice, slice };
+
+        bounds = executeBuildBound(cfDef, restrictions, Bound.START);
+        assertEquals(1, bounds.size());
+        assertComposite(cfDef, bounds.get(0));
+
+        bounds = executeBuildBound(cfDef, restrictions, Bound.END);
+        assertEquals(1, bounds.size());
+        assertForRelationComposite(cfDef, bounds.get(0), Relation.Type.LT, value1, value2);
+
+        // (clustering_0, clustering1) > (1, 2) AND (clustering_0) < (2)
+        slice = new MultiColumnRestriction.Slice(false);
+        slice.setBound(Relation.Type.GT, toMultiItemTerminal(value1, value2));
+        slice.setBound(Relation.Type.LT, toMultiItemTerminal(value2));
+        restrictions = new Restriction[] { slice, slice };
+
+        bounds = executeBuildBound(cfDef, restrictions, Bound.START);
+        assertEquals(1, bounds.size());
+        assertForRelationComposite(cfDef, bounds.get(0), Relation.Type.GT, value1, value2);
+
+        bounds = executeBuildBound(cfDef, restrictions, Bound.END);
+        assertEquals(1, bounds.size());
+        assertForRelationComposite(cfDef, bounds.get(0), Relation.Type.LT, value2);
+
+        // (clustering_0, clustering1) >= (1, 2) AND (clustering_0, clustering1) <=
(2, 1)
+        slice = new MultiColumnRestriction.Slice(false);
+        slice.setBound(Relation.Type.GTE, toMultiItemTerminal(value1, value2));
+        slice.setBound(Relation.Type.LTE, toMultiItemTerminal(value2, value1));
+        restrictions = new Restriction[] { slice, slice };
+
+        bounds = executeBuildBound(cfDef, restrictions, Bound.START);
+        assertEquals(1, bounds.size());
+        assertForRelationComposite(cfDef, bounds.get(0), Relation.Type.GTE, value1, value2);
+
+        bounds = executeBuildBound(cfDef, restrictions, Bound.END);
+        assertEquals(1, bounds.size());
+        assertForRelationComposite(cfDef, bounds.get(0), Relation.Type.LTE, value2, value1);
+    }
+
+    /**
+     * Test mixing single and multi equals restrictions (e.g. clustering_0 = 1 AND (clustering_1,
clustering_2) = (2, 3))
+     */
+    @Test
+    public void testBuildBoundWithSingleEqAndMultiEqRestrictions() throws Exception
+    {
+        ByteBuffer value1 = ByteBufferUtil.bytes(1);
+        ByteBuffer value2 = ByteBufferUtil.bytes(2);
+        ByteBuffer value3 = ByteBufferUtil.bytes(3);
+        ByteBuffer value4 = ByteBufferUtil.bytes(4);
+
+        // clustering_0 = 1 AND (clustering_1, clustering_2) = (2, 3)
+        SingleColumnRestriction.EQ singleEq = new SingleColumnRestriction.EQ(toTerm(value1),
false);
+        MultiColumnRestriction.EQ multiEq = new MultiColumnRestriction.EQ(toMultiItemTerminal(value2,
value3), false);
+        Restriction[] restrictions = new Restriction[] { singleEq, multiEq, multiEq };
+        CFDefinition cfDef = createCFDefinition(restrictions.length);
+
+        List<ByteBuffer> bounds = executeBuildBound(cfDef, restrictions, Bound.START);
+        assertEquals(1, bounds.size());
+        assertComposite(cfDef, bounds.get(0), value1, value2, value3);
+
+        bounds = executeBuildBound(cfDef, restrictions, Bound.END);
+        assertEquals(1, bounds.size());
+        assertComposite(cfDef, bounds.get(0), value1, value2, value3);
+
+        // clustering_0 = 1 AND clustering_1 = 2 AND (clustering_2, clustering_3) = (3, 4)
+        singleEq = new SingleColumnRestriction.EQ(toTerm(value1), false);
+        SingleColumnRestriction.EQ singleEq2 = new SingleColumnRestriction.EQ(toTerm(value2),
false);
+        multiEq = new MultiColumnRestriction.EQ(toMultiItemTerminal(value3, value4), false);
+        restrictions = new Restriction[] { singleEq, singleEq2, multiEq, multiEq };
+        cfDef = createCFDefinition(restrictions.length);
+
+        bounds = executeBuildBound(cfDef, restrictions, Bound.START);
+        assertEquals(1, bounds.size());
+        assertComposite(cfDef, bounds.get(0), value1, value2, value3, value4);
+
+        bounds = executeBuildBound(cfDef, restrictions, Bound.END);
+        assertEquals(1, bounds.size());
+        assertComposite(cfDef, bounds.get(0), value1, value2, value3, value4);
+
+        // (clustering_0, clustering_1) = (1, 2) AND clustering_2 = 3
+        singleEq = new SingleColumnRestriction.EQ(toTerm(value3), false);
+        multiEq = new MultiColumnRestriction.EQ(toMultiItemTerminal(value1, value2), false);
+        restrictions = new Restriction[] { multiEq, multiEq, singleEq };
+        cfDef = createCFDefinition(restrictions.length);
+
+        bounds = executeBuildBound(cfDef, restrictions, Bound.START);
+        assertEquals(1, bounds.size());
+        assertComposite(cfDef, bounds.get(0), value1, value2, value3);
+
+        bounds = executeBuildBound(cfDef, restrictions, Bound.END);
+        assertEquals(1, bounds.size());
+        assertComposite(cfDef, bounds.get(0), value1, value2, value3);
+
+        // clustering_0 = 1 AND (clustering_1, clustering_2) = (2, 3) AND clustering_3 =
4
+        singleEq = new SingleColumnRestriction.EQ(toTerm(value1), false);
+        singleEq2 = new SingleColumnRestriction.EQ(toTerm(value4), false);
+        multiEq = new MultiColumnRestriction.EQ(toMultiItemTerminal(value2, value3), false);
+        restrictions = new Restriction[] { singleEq, multiEq, multiEq, singleEq2 };
+        cfDef = createCFDefinition(restrictions.length);
+
+        bounds = executeBuildBound(cfDef, restrictions, Bound.START);
+        assertEquals(1, bounds.size());
+        assertComposite(cfDef, bounds.get(0), value1, value2, value3, value4);
+
+        bounds = executeBuildBound(cfDef, restrictions, Bound.END);
+        assertEquals(1, bounds.size());
+        assertComposite(cfDef, bounds.get(0), value1, value2, value3, value4);
+    }
+
+    /**
+     * Test clustering_0 = 1 AND (clustering_1, clustering_2) IN ((2, 3), (4, 5))
+     */
+    @Test
+    public void testBuildBoundWithSingleEqAndMultiINRestrictions() throws Exception
+    {
+        ByteBuffer value1 = ByteBufferUtil.bytes(1);
+        ByteBuffer value2 = ByteBufferUtil.bytes(2);
+        ByteBuffer value3 = ByteBufferUtil.bytes(3);
+        ByteBuffer value4 = ByteBufferUtil.bytes(4);
+        ByteBuffer value5 = ByteBufferUtil.bytes(5);
+
+        // clustering_0 = 1 AND (clustering_1, clustering_2) IN ((2, 3), (4, 5))
+        SingleColumnRestriction.EQ singleEq = new SingleColumnRestriction.EQ(toTerm(value1),
false);
+        MultiColumnRestriction.IN multiIn =
+                new MultiColumnRestriction.InWithValues(asList(toMultiItemTerminal(value2,
value3),
+                                                               toMultiItemTerminal(value4,
value5)));
+
+        Restriction[] restrictions = new Restriction[] { singleEq, multiIn, multiIn };
+        CFDefinition cfDef = createCFDefinition(restrictions.length);
+
+        List<ByteBuffer> bounds = executeBuildBound(cfDef, restrictions, Bound.START);
+        assertEquals(2, bounds.size());
+        assertComposite(cfDef, bounds.get(0), value1, value2, value3);
+        assertComposite(cfDef, bounds.get(1), value1, value4, value5);
+
+        bounds = executeBuildBound(cfDef, restrictions, Bound.END);
+        assertEquals(2, bounds.size());
+        assertComposite(cfDef, bounds.get(0), value1, value2, value3);
+        assertComposite(cfDef, bounds.get(1), value1, value4, value5);
+
+        // clustering_0 = 1 AND (clustering_1, clustering_2) IN ((2, 3))
+        singleEq = new SingleColumnRestriction.EQ(toTerm(value1), false);
+        multiIn = new MultiColumnRestriction.InWithValues(asList(toMultiItemTerminal(value2,
value3),
+                                                                 toMultiItemTerminal(value4,
value5)));
+
+        restrictions = new Restriction[] { singleEq, multiIn, multiIn };
+        cfDef = createCFDefinition(restrictions.length);
+
+        bounds = executeBuildBound(cfDef, restrictions, Bound.START);
+        assertEquals(2, bounds.size());
+        assertComposite(cfDef, bounds.get(0), value1, value2, value3);
+        assertComposite(cfDef, bounds.get(1), value1, value4, value5);
+
+        // clustering_0 = 1 AND clustering_1 = 5 AND (clustering_2, clustering_3) IN ((2,
3), (4, 5))
+        singleEq = new SingleColumnRestriction.EQ(toTerm(value1), false);
+        SingleColumnRestriction.EQ singleEq2 = new SingleColumnRestriction.EQ(toTerm(value5),
false);
+        multiIn = new MultiColumnRestriction.InWithValues(asList(toMultiItemTerminal(value2,
value3),
+                                                                 toMultiItemTerminal(value4,
value5)));
+
+        restrictions = new Restriction[] { singleEq, singleEq2, multiIn, multiIn };
+        cfDef = createCFDefinition(restrictions.length);
+
+        bounds = executeBuildBound(cfDef, restrictions, Bound.START);
+        assertEquals(2, bounds.size());
+        assertComposite(cfDef, bounds.get(0), value1, value5, value2, value3);
+        assertComposite(cfDef, bounds.get(1), value1, value5, value4, value5);
+
+        bounds = executeBuildBound(cfDef, restrictions, Bound.END);
+        assertEquals(2, bounds.size());
+        assertComposite(cfDef, bounds.get(0), value1, value5, value2, value3);
+        assertComposite(cfDef, bounds.get(1), value1, value5, value4, value5);
+    }
+
+    /**
+     * Test mixing single equal restrictions with multi-column slice restrictions
+     * (e.g. clustering_0 = 1 AND (clustering_1, clustering_2) > (2, 3))
+     */
+    @Test
+    public void testBuildBoundWithSingleEqAndSliceRestrictions() throws Exception
+    {
+        ByteBuffer value1 = ByteBufferUtil.bytes(1);
+        ByteBuffer value2 = ByteBufferUtil.bytes(2);
+        ByteBuffer value3 = ByteBufferUtil.bytes(3);
+        ByteBuffer value4 = ByteBufferUtil.bytes(4);
+        ByteBuffer value5 = ByteBufferUtil.bytes(5);
+
+        // clustering_0 = 1 AND (clustering_1, clustering_2) > (2, 3)
+        SingleColumnRestriction.EQ singleEq = new SingleColumnRestriction.EQ(toTerm(value1),
false);
+        MultiColumnRestriction.Slice multiSlice = new MultiColumnRestriction.Slice(false);
+        multiSlice.setBound(Relation.Type.GT, toMultiItemTerminal(value2, value3));
+
+        Restriction[] restrictions = new Restriction[] { singleEq, multiSlice, multiSlice
};
+        CFDefinition cfDef = createCFDefinition(restrictions.length);
+
+        List<ByteBuffer> bounds = executeBuildBound(cfDef, restrictions, Bound.START);
+        assertEquals(1, bounds.size());
+        assertForRelationComposite(cfDef, bounds.get(0), Relation.Type.GT, value1, value2,
value3);
+
+        bounds = executeBuildBound(cfDef, restrictions, Bound.END);
+        assertEquals(1, bounds.size());
+        assertEndOfRangeComposite(cfDef, bounds.get(0), value1);
+
+        // clustering_0 = 1 AND (clustering_1, clustering_2) > (2, 3) AND (clustering_1)
< (4)
+        singleEq = new SingleColumnRestriction.EQ(toTerm(value1), false);
+        multiSlice = new MultiColumnRestriction.Slice(false);
+        multiSlice.setBound(Relation.Type.GT, toMultiItemTerminal(value2, value3));
+        multiSlice.setBound(Relation.Type.LT, toMultiItemTerminal(value4));
+
+        restrictions = new Restriction[] { singleEq, multiSlice, multiSlice };
+
+        bounds = executeBuildBound(cfDef, restrictions, Bound.START);
+        assertEquals(1, bounds.size());
+        assertForRelationComposite(cfDef, bounds.get(0), Relation.Type.GT, value1, value2,
value3);
+
+        bounds = executeBuildBound(cfDef, restrictions, Bound.END);
+        assertEquals(1, bounds.size());
+        assertForRelationComposite(cfDef, bounds.get(0), Relation.Type.LT, value1, value4);
+
+        // clustering_0 = 1 AND (clustering_1, clustering_2) => (2, 3) AND (clustering_1,
clustering_2) <= (4, 5)
+        singleEq = new SingleColumnRestriction.EQ(toTerm(value1), false);
+        multiSlice = new MultiColumnRestriction.Slice(false);
+        multiSlice.setBound(Relation.Type.GTE, toMultiItemTerminal(value2, value3));
+        multiSlice.setBound(Relation.Type.LTE, toMultiItemTerminal(value4, value5));
+
+        restrictions = new Restriction[] { singleEq, multiSlice, multiSlice };
+
+        bounds = executeBuildBound(cfDef, restrictions, Bound.START);
+        assertEquals(1, bounds.size());
+        assertForRelationComposite(cfDef, bounds.get(0), Relation.Type.GTE, value1, value2,
value3);
+
+        bounds = executeBuildBound(cfDef, restrictions, Bound.END);
+        assertEquals(1, bounds.size());
+        assertForRelationComposite(cfDef, bounds.get(0), Relation.Type.LTE, value1, value4,
value5);
+    }
+
+    /**
+     * Test mixing multi equal restrictions with single-column slice restrictions
+     * (e.g. clustering_0 = 1 AND (clustering_1, clustering_2) > (2, 3))
+     */
+    @Test
+    public void testBuildBoundWithMultiEqAndSingleSliceRestrictions() throws Exception
+    {
+        ByteBuffer value1 = ByteBufferUtil.bytes(1);
+        ByteBuffer value2 = ByteBufferUtil.bytes(2);
+        ByteBuffer value3 = ByteBufferUtil.bytes(3);
+
+        // (clustering_0, clustering_1) = (1, 2) AND clustering_2 > 3
+        MultiColumnRestriction.EQ multiEq = new MultiColumnRestriction.EQ(toMultiItemTerminal(value1,
value2), false);
+        SingleColumnRestriction.Slice singleSlice = new SingleColumnRestriction.Slice(false);
+        singleSlice.setBound(Relation.Type.GT, toTerm(value3));
+
+        Restriction[] restrictions = new Restriction[] { multiEq, multiEq, singleSlice };
+        CFDefinition cfDef = createCFDefinition(restrictions.length);
+
+        List<ByteBuffer> bounds = executeBuildBound(cfDef, restrictions, Bound.START);
+        assertEquals(1, bounds.size());
+        assertForRelationComposite(cfDef, bounds.get(0), Relation.Type.GT, value1, value2,
value3);
+
+        bounds = executeBuildBound(cfDef, restrictions, Bound.END);
+        assertEquals(1, bounds.size());
+        assertEndOfRangeComposite(cfDef, bounds.get(0), value1, value2);
+    }
+
+    @Test
+    public void testBuildBoundWithSeveralMultiColumnRestrictions() throws Exception
+    {
+        ByteBuffer value1 = ByteBufferUtil.bytes(1);
+        ByteBuffer value2 = ByteBufferUtil.bytes(2);
+        ByteBuffer value3 = ByteBufferUtil.bytes(3);
+        ByteBuffer value4 = ByteBufferUtil.bytes(4);
+        ByteBuffer value5 = ByteBufferUtil.bytes(5);
+
+        // (clustering_0, clustering_1) = (1, 2) AND (clustering_2, clustering_3) > (3,
4)
+        MultiColumnRestriction.EQ multiEq = new MultiColumnRestriction.EQ(toMultiItemTerminal(value1,
value2), false);
+        MultiColumnRestriction.Slice multiSlice = new MultiColumnRestriction.Slice(false);
+        multiSlice.setBound(Relation.Type.GT, toMultiItemTerminal(value3, value4));
+
+        Restriction[] restrictions = new Restriction[] { multiEq, multiEq, multiSlice, multiSlice};
+        CFDefinition cfDef = createCFDefinition(restrictions.length);
+
+        List<ByteBuffer> bounds = executeBuildBound(cfDef, restrictions, Bound.START);
+        assertEquals(1, bounds.size());
+        assertForRelationComposite(cfDef, bounds.get(0), Relation.Type.GT,value1, value2,
value3, value4);
+
+        bounds = executeBuildBound(cfDef, restrictions, Bound.END);
+        assertEquals(1, bounds.size());
+        assertEndOfRangeComposite(cfDef, bounds.get(0),  value1, value2);
+
+        // (clustering_0, clustering_1) = (1, 2) AND (clustering_2, clustering_3) IN ((3,
4), (4, 5))
+        multiEq = new MultiColumnRestriction.EQ(toMultiItemTerminal(value1, value2), false);
+        MultiColumnRestriction.IN multiIn =
+                new MultiColumnRestriction.InWithValues(asList(toMultiItemTerminal(value3,
value4),
+                                                               toMultiItemTerminal(value4,
value5)));
+
+        restrictions = new Restriction[] { multiEq, multiEq, multiIn, multiIn};
+        cfDef = createCFDefinition(restrictions.length);
+
+        bounds = executeBuildBound(cfDef, restrictions, Bound.START);
+        assertEquals(2, bounds.size());
+        assertComposite(cfDef, bounds.get(0), value1, value2, value3, value4);
+        assertComposite(cfDef, bounds.get(1), value1, value2, value4, value5);
+
+        bounds = executeBuildBound(cfDef, restrictions, Bound.END);
+        assertEquals(2, bounds.size());
+        assertComposite(cfDef, bounds.get(0), value1, value2, value3, value4);
+        assertComposite(cfDef, bounds.get(1), value1, value2, value4, value5);
+
+        // (clustering_0, clustering_1) = (1, 2) AND (clustering_2, clustering_3) = ((3,
4), (4, 5))
+        multiEq = new MultiColumnRestriction.EQ(toMultiItemTerminal(value1, value2), false);
+        MultiColumnRestriction.EQ multiEq2 = new MultiColumnRestriction.EQ(toMultiItemTerminal(value3,
value4), false);
+
+        restrictions = new Restriction[] { multiEq, multiEq, multiEq2, multiEq2};
+        cfDef = createCFDefinition(restrictions.length);
+
+        bounds = executeBuildBound(cfDef, restrictions, Bound.START);
+        assertEquals(1, bounds.size());
+        assertComposite(cfDef, bounds.get(0), value1, value2, value3, value4);
+
+        bounds = executeBuildBound(cfDef, restrictions, Bound.END);
+        assertEquals(1, bounds.size());
+        assertComposite(cfDef, bounds.get(0), value1, value2, value3, value4);
+    }
+
+    /**
+     * Asserts that the specified composite contains the specified elements.
+     *
+     * @param cfDef the Column Family Definition
+     * @param actual the buffer to test
+     * @param elements the expected elements of the composite
+     */
+    private static void assertComposite(CFDefinition cfDef, ByteBuffer actual, ByteBuffer...
elements)
+    {
+        ColumnNameBuilder builder = addElements(cfDef.getColumnNameBuilder(), elements);
+        assertArrayEquals("the composite is not the expected one:", actual.array(), builder.build().array());
+    }
+
+    /**
+     * Asserts that the specified composite is an end of range composite that contains the
specified elements.
+     *
+     * @param cfDef the Column Family Definition
+     * @param actual the buffer to test
+     * @param elements the expected elements of the composite
+     */
+    private static void assertEndOfRangeComposite(CFDefinition cfDef, ByteBuffer actual,
ByteBuffer... elements)
+    {
+        ColumnNameBuilder builder = addElements(cfDef.getColumnNameBuilder(), elements);
+        assertArrayEquals("the composite is not the expected one:", actual.array(), builder.buildAsEndOfRange().array());
+    }
+
+    /**
+     * Asserts that the specified composite is an end of range composite that contains the
specified elements.
+     *
+     * @param cfDef the Column Family Definition
+     * @param actual the buffer to test
+     * @param elements the expected elements of the composite
+     */
+    private static void assertForRelationComposite(CFDefinition cfDef,
+                                                   ByteBuffer actual,
+                                                   Relation.Type relType,
+                                                   ByteBuffer... elements)
+    {
+        ColumnNameBuilder builder = addElements(cfDef.getColumnNameBuilder(), elements);
+        assertArrayEquals("the composite is not the expected one:", actual.array(), builder.buildForRelation(relType).array());
+    }
+
+    /**
+     * Adds all the specified elements to the specified builder.
+     *
+     * @param builder the builder to add to
+     * @param elements the elements to add
+     * @return the builder
+     */
+    private static ColumnNameBuilder addElements(ColumnNameBuilder builder, ByteBuffer...
elements)
+    {
+        for (int i = 0, m = elements.length; i < m; i++)
+            builder.add(elements[i]);
+        return builder;
+    }
+
+    /**
+     * Calls the <code>SelectStatement.buildBound</code> with the specified restrictions.
+     *
+     * @param cfDef the Column Family Definition
+     * @param restrictions the restrictions
+     * @return the result from the method call to <code>SelectStatement.buildBound</code>
+     * @throws InvalidRequestException if buildBound throw an <code>Exception</code>
+     */
+    private static List<ByteBuffer> executeBuildBound(CFDefinition cfDef,
+                                                      Restriction[] restrictions,
+                                                      Bound bound) throws InvalidRequestException
+    {
+        return SelectStatement.buildBound(bound,
+                                          new ArrayList<Name>(cfDef.clusteringColumns()),
+                                          restrictions,
+                                          false,
+                                          cfDef,
+                                          cfDef.getColumnNameBuilder(),
+                                          Collections.<ByteBuffer>emptyList());
+    }
+
+    /**
+     * Creates a <code>CFDefinition</code> to be used in the tests.
+     *
+     * @param numberOfClusteringColumns the number of clustering columns
+     * @return a new a <code>CFDefinition</code> instance
+     * @throws ConfigurationException if the CFDefinition cannot be created
+     */
+    private static CFDefinition createCFDefinition(int numberOfClusteringColumns) throws
ConfigurationException
+    {
+        List<AbstractType<?>> types = new ArrayList<>();
+        for (int i = 0, m = numberOfClusteringColumns; i < m; i++)
+            types.add(Int32Type.instance);
+
+        CompositeType cType = CompositeType.getInstance(types);
+        CFMetaData cfMetaData = new CFMetaData("keyspace", "test", ColumnFamilyType.Standard,
cType);
+        ByteBuffer partitionKey = ByteBufferUtil.bytes("partitionKey");
+        cfMetaData.addColumnDefinition(ColumnDefinition.partitionKeyDef(partitionKey, Int32Type.instance,
0));
+
+        for (int i = 0, m = numberOfClusteringColumns; i < m; i++)
+        {
+            ByteBuffer name = ByteBufferUtil.bytes("clustering_" + i);
+            cfMetaData.addColumnDefinition(ColumnDefinition.clusteringKeyDef(name, types.get(i),
i));
+        }
+        cfMetaData.rebuild();
+        return new CFDefinition(cfMetaData);
+    }
+
+    /**
+     * Converts the specified values into a <code>MultiItemTerminal</code>.
+     *
+     * @param values the values to convert.
+     * @return the term corresponding to the specified values.
+     */
+    private static Term toMultiItemTerminal(ByteBuffer... values)
+    {
+        return new Tuples.Value(values);
+    }
+
+    /**
+     * Converts the specified value into a term.
+     *
+     * @param value the value to convert.
+     * @return the term corresponding to the specified value.
+     */
+    private static Term toTerm(ByteBuffer value)
+    {
+        return new Constants.Value(value);
+    }
+
+    /**
+     * Converts the specified values into a <code>List</code> of terms.
+     *
+     * @param values the values to convert.
+     * @return a <code>List</code> of terms corresponding to the specified values.
+     */
+    private static List<Term> toTerms(ByteBuffer... values)
+    {
+        List<Term> terms = new ArrayList<>();
+        for (ByteBuffer value : values)
+            terms.add(toTerm(value));
+        return terms;
+    }
+}


Mime
View raw message