You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cassandra.apache.org by bl...@apache.org on 2015/09/17 21:50:16 UTC

[1/3] cassandra git commit: Merge cassandra-2.2 into cassandra-3.0

Repository: cassandra
Updated Branches:
  refs/heads/trunk 0bae8034d -> d6d5698b8


Merge cassandra-2.2 into cassandra-3.0


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

Branch: refs/heads/trunk
Commit: a90de7c61df62adba6af753b28653c241ddd27fb
Parents: 2db8370
Author: blerer <be...@datastax.com>
Authored: Thu Sep 17 21:38:42 2015 +0200
Committer: blerer <be...@datastax.com>
Committed: Thu Sep 17 21:40:52 2015 +0200

----------------------------------------------------------------------
 NEWS.txt                                        |  6 ++
 .../cassandra/cql3/BatchQueryOptions.java       | 28 ++++++++
 .../cassandra/cql3/ColumnSpecification.java     | 10 +++
 .../org/apache/cassandra/cql3/QueryOptions.java | 70 +++++++++++++++++++-
 .../cql3/statements/BatchStatement.java         |  2 +-
 .../transport/messages/BatchMessage.java        |  2 +-
 .../transport/messages/ExecuteMessage.java      |  5 +-
 .../cql3/validation/operations/BatchTest.java   | 10 +--
 8 files changed, 124 insertions(+), 9 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cassandra/blob/a90de7c6/NEWS.txt
----------------------------------------------------------------------
diff --git a/NEWS.txt b/NEWS.txt
index 4b35f71..b6730a1 100644
--- a/NEWS.txt
+++ b/NEWS.txt
@@ -118,6 +118,12 @@ Changed Defaults
      of the total space of the commitlog volume. (Before: always used
      8192)
 
+New features
+------------
+   - Custom QueryHandlers can retrieve the column specifications for the bound
+     variables from QueryOptions by using the hasColumnSpecifications()
+     and getColumnSpecifications() methods.
+
 
 2.2.1
 =====

http://git-wip-us.apache.org/repos/asf/cassandra/blob/a90de7c6/src/java/org/apache/cassandra/cql3/BatchQueryOptions.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/cql3/BatchQueryOptions.java b/src/java/org/apache/cassandra/cql3/BatchQueryOptions.java
index 2fcee5b..db7fa39 100644
--- a/src/java/org/apache/cassandra/cql3/BatchQueryOptions.java
+++ b/src/java/org/apache/cassandra/cql3/BatchQueryOptions.java
@@ -22,6 +22,8 @@ import java.util.ArrayList;
 import java.util.Collections;
 import java.util.List;
 
+import org.apache.cassandra.utils.MD5Digest;
+
 import org.apache.cassandra.db.ConsistencyLevel;
 import org.apache.cassandra.service.QueryState;
 
@@ -50,6 +52,11 @@ public abstract class BatchQueryOptions
 
     public abstract QueryOptions forStatement(int i);
 
+    public void prepareStatement(int i, List<ColumnSpecification> boundNames)
+    {
+        forStatement(i).prepare(boundNames);
+    }
+
     public ConsistencyLevel getConsistency()
     {
         return wrapped.getConsistency();
@@ -107,5 +114,26 @@ public abstract class BatchQueryOptions
         {
             return perStatementOptions.get(i);
         }
+
+        @Override
+        public void prepareStatement(int i, List<ColumnSpecification> boundNames)
+        {
+            if (isPreparedStatement(i))
+            {
+                QueryOptions options = perStatementOptions.get(i);
+                options.prepare(boundNames);
+                options = QueryOptions.addColumnSpecifications(options, boundNames);
+                perStatementOptions.set(i, options);
+            }
+            else
+            {
+                super.prepareStatement(i, boundNames);
+            }
+        }
+
+        private boolean isPreparedStatement(int i)
+        {
+            return getQueryOrIdList().get(i) instanceof MD5Digest;
+        }
     }
 }

http://git-wip-us.apache.org/repos/asf/cassandra/blob/a90de7c6/src/java/org/apache/cassandra/cql3/ColumnSpecification.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/cql3/ColumnSpecification.java b/src/java/org/apache/cassandra/cql3/ColumnSpecification.java
index e12a57e..e64f5f9 100644
--- a/src/java/org/apache/cassandra/cql3/ColumnSpecification.java
+++ b/src/java/org/apache/cassandra/cql3/ColumnSpecification.java
@@ -18,6 +18,7 @@
 package org.apache.cassandra.cql3;
 
 import com.google.common.base.Objects;
+
 import org.apache.cassandra.db.marshal.AbstractType;
 import org.apache.cassandra.db.marshal.ReversedType;
 
@@ -91,4 +92,13 @@ public class ColumnSpecification
     {
         return Objects.hashCode(ksName, cfName, name, type);
     }
+
+    @Override
+    public String toString()
+    {
+        return Objects.toStringHelper(this)
+                      .add("name", name)
+                      .add("type", type)
+                      .toString();
+    }
 }

http://git-wip-us.apache.org/repos/asf/cassandra/blob/a90de7c6/src/java/org/apache/cassandra/cql3/QueryOptions.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/cql3/QueryOptions.java b/src/java/org/apache/cassandra/cql3/QueryOptions.java
index 672f8ea..ad554ed 100644
--- a/src/java/org/apache/cassandra/cql3/QueryOptions.java
+++ b/src/java/org/apache/cassandra/cql3/QueryOptions.java
@@ -23,8 +23,9 @@ import java.util.Collections;
 import java.util.EnumSet;
 import java.util.List;
 
-import io.netty.buffer.ByteBuf;
+import com.google.common.collect.ImmutableList;
 
+import io.netty.buffer.ByteBuf;
 import org.apache.cassandra.db.ConsistencyLevel;
 import org.apache.cassandra.service.QueryState;
 import org.apache.cassandra.service.pager.PagingState;
@@ -72,10 +73,43 @@ public abstract class QueryOptions
         return new DefaultQueryOptions(consistency, values, skipMetadata, new SpecificOptions(pageSize, pagingState, serialConsistency, -1L), 0);
     }
 
+    public static QueryOptions addColumnSpecifications(QueryOptions options, List<ColumnSpecification> columnSpecs)
+    {
+        return new OptionsWithColumnSpecifications(options, columnSpecs);
+    }
+
     public abstract ConsistencyLevel getConsistency();
     public abstract List<ByteBuffer> getValues();
     public abstract boolean skipMetadata();
 
+    /**
+     * Tells whether or not this <code>QueryOptions</code> contains the column specifications for the bound variables.
+     * <p>The column specifications will be present only for prepared statements.</p>
+     * @return <code>true</code> this <code>QueryOptions</code> contains the column specifications for the bound
+     * variables, <code>false</code> otherwise.
+     */
+    public boolean hasColumnSpecifications()
+    {
+        return false;
+    }
+
+    /**
+     * Returns the column specifications for the bound variables (<i>optional operation</i>).
+     *
+     * <p>The column specifications will be present only for prepared statements.</p>
+     *
+     * <p>Invoke the {@link hasColumnSpecifications} method before invoking this method in order to ensure that this
+     * <code>QueryOptions</code> contains the column specifications.</p>
+     *
+     * @return the option names
+     * @throws UnsupportedOperationException If this <code>QueryOptions</code> does not contains the column
+     * specifications.
+     */
+    public ImmutableList<ColumnSpecification> getColumnSpecifications()
+    {
+        throw new UnsupportedOperationException();
+    }
+
     /**  The pageSize for this query. Will be <= 0 if not relevant for the query.  */
     public int getPageSize()
     {
@@ -159,7 +193,7 @@ public abstract class QueryOptions
         }
     }
 
-    static abstract class QueryOptionsWrapper extends QueryOptions
+    static class QueryOptionsWrapper extends QueryOptions
     {
         protected final QueryOptions wrapped;
 
@@ -168,6 +202,11 @@ public abstract class QueryOptions
             this.wrapped = wrapped;
         }
 
+        public List<ByteBuffer> getValues()
+        {
+            return this.wrapped.getValues();
+        }
+
         public ConsistencyLevel getConsistency()
         {
             return wrapped.getConsistency();
@@ -196,6 +235,32 @@ public abstract class QueryOptions
         }
     }
 
+    /**
+     * <code>QueryOptions</code> decorator that provides access to the column specifications.
+     */
+    static class OptionsWithColumnSpecifications extends QueryOptionsWrapper
+    {
+        private final ImmutableList<ColumnSpecification> columnSpecs;
+
+        OptionsWithColumnSpecifications(QueryOptions wrapped, List<ColumnSpecification> columnSpecs)
+        {
+            super(wrapped);
+            this.columnSpecs = ImmutableList.copyOf(columnSpecs);
+        }
+
+        @Override
+        public boolean hasColumnSpecifications()
+        {
+            return true;
+        }
+
+        @Override
+        public ImmutableList<ColumnSpecification> getColumnSpecifications()
+        {
+            return columnSpecs;
+        }
+    }
+
     static class OptionsWithNames extends QueryOptionsWrapper
     {
         private final List<String> names;
@@ -228,6 +293,7 @@ public abstract class QueryOptions
             return this;
         }
 
+        @Override
         public List<ByteBuffer> getValues()
         {
             assert orderedValues != null; // We should have called prepare first!

http://git-wip-us.apache.org/repos/asf/cassandra/blob/a90de7c6/src/java/org/apache/cassandra/cql3/statements/BatchStatement.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/cql3/statements/BatchStatement.java b/src/java/org/apache/cassandra/cql3/statements/BatchStatement.java
index 4a92ec1..0b3e1ba 100644
--- a/src/java/org/apache/cassandra/cql3/statements/BatchStatement.java
+++ b/src/java/org/apache/cassandra/cql3/statements/BatchStatement.java
@@ -519,7 +519,7 @@ public class BatchStatement implements CQLStatement
 
             // Use the CFMetadata of the first statement for partition key bind indexes.  If the statements affect
             // multiple tables, we won't send partition key bind indexes.
-            Short[] partitionKeyBindIndexes = haveMultipleCFs ? null
+            Short[] partitionKeyBindIndexes = (haveMultipleCFs || batchStatement.statements.isEmpty())? null
                                                               : boundNames.getPartitionKeyBindIndexes(batchStatement.statements.get(0).cfm);
 
             return new ParsedStatement.Prepared(batchStatement, boundNames, partitionKeyBindIndexes);

http://git-wip-us.apache.org/repos/asf/cassandra/blob/a90de7c6/src/java/org/apache/cassandra/transport/messages/BatchMessage.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/transport/messages/BatchMessage.java b/src/java/org/apache/cassandra/transport/messages/BatchMessage.java
index 5baf1a6..bd2423e 100644
--- a/src/java/org/apache/cassandra/transport/messages/BatchMessage.java
+++ b/src/java/org/apache/cassandra/transport/messages/BatchMessage.java
@@ -203,7 +203,7 @@ public class BatchMessage extends Message.Request
             for (int i = 0; i < prepared.size(); i++)
             {
                 ParsedStatement.Prepared p = prepared.get(i);
-                batchOptions.forStatement(i).prepare(p.boundNames);
+                batchOptions.prepareStatement(i, p.boundNames);
 
                 if (!(p.statement instanceof ModificationStatement))
                     throw new InvalidRequestException("Invalid statement in batch: only UPDATE, INSERT and DELETE statements are allowed.");

http://git-wip-us.apache.org/repos/asf/cassandra/blob/a90de7c6/src/java/org/apache/cassandra/transport/messages/ExecuteMessage.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/transport/messages/ExecuteMessage.java b/src/java/org/apache/cassandra/transport/messages/ExecuteMessage.java
index 940a0fc..e9923b4 100644
--- a/src/java/org/apache/cassandra/transport/messages/ExecuteMessage.java
+++ b/src/java/org/apache/cassandra/transport/messages/ExecuteMessage.java
@@ -124,7 +124,10 @@ public class ExecuteMessage extends Message.Request
                 Tracing.instance.begin("Execute CQL3 prepared query", state.getClientAddress(), builder.build());
             }
 
-            Message.Response response = handler.processPrepared(statement, state, options, getCustomPayload());
+            // Some custom QueryHandlers are interested by the bound names. We provide them this information
+            // by wrapping the QueryOptions.
+            QueryOptions queryOptions = QueryOptions.addColumnSpecifications(options, prepared.boundNames);
+            Message.Response response = handler.processPrepared(statement, state, queryOptions, getCustomPayload());
             if (options.skipMetadata() && response instanceof ResultMessage.Rows)
                 ((ResultMessage.Rows)response).result.metadata.setSkipMetadata();
 

http://git-wip-us.apache.org/repos/asf/cassandra/blob/a90de7c6/test/unit/org/apache/cassandra/cql3/validation/operations/BatchTest.java
----------------------------------------------------------------------
diff --git a/test/unit/org/apache/cassandra/cql3/validation/operations/BatchTest.java b/test/unit/org/apache/cassandra/cql3/validation/operations/BatchTest.java
index c0d1df5..43e3a30 100644
--- a/test/unit/org/apache/cassandra/cql3/validation/operations/BatchTest.java
+++ b/test/unit/org/apache/cassandra/cql3/validation/operations/BatchTest.java
@@ -18,12 +18,8 @@
 
 package org.apache.cassandra.cql3.validation.operations;
 
-import java.util.Arrays;
-
 import org.junit.Test;
 
-import static org.apache.commons.lang3.StringUtils.isEmpty;
-
 import org.apache.cassandra.cql3.CQLTester;
 
 public class BatchTest extends CQLTester
@@ -172,4 +168,10 @@ public class BatchTest extends CQLTester
                    row(0, 5, 20),
                    row(0, 6, 20));
     }
+
+    @Test
+    public void testBatchEmpty() throws Throwable
+    {
+        assertEmpty(execute("BEGIN BATCH APPLY BATCH;"));
+    }
 }


[3/3] cassandra git commit: Merge branch cassandra-3.0 into trunk

Posted by bl...@apache.org.
Merge branch cassandra-3.0 into trunk


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

Branch: refs/heads/trunk
Commit: d6d5698b8d04aad546174813f908a4e1a5752f73
Parents: 0bae803 caadcf6
Author: blerer <be...@datastax.com>
Authored: Thu Sep 17 21:48:20 2015 +0200
Committer: blerer <be...@datastax.com>
Committed: Thu Sep 17 21:48:48 2015 +0200

----------------------------------------------------------------------
 NEWS.txt                                        |  6 ++
 .../cassandra/cql3/BatchQueryOptions.java       | 28 ++++++++
 .../cassandra/cql3/ColumnSpecification.java     | 10 +++
 .../org/apache/cassandra/cql3/QueryOptions.java | 70 +++++++++++++++++++-
 .../cql3/statements/BatchStatement.java         |  2 +-
 .../cql3/statements/DropTableStatement.java     |  2 +-
 .../transport/messages/BatchMessage.java        |  2 +-
 .../transport/messages/ExecuteMessage.java      |  5 +-
 .../org/apache/cassandra/cql3/ViewTest.java     | 50 +++++++++++---
 .../cql3/validation/operations/BatchTest.java   | 10 +--
 10 files changed, 166 insertions(+), 19 deletions(-)
----------------------------------------------------------------------



[2/3] cassandra git commit: Make DropTableStatement throw an error if the table is a view

Posted by bl...@apache.org.
Make DropTableStatement throw an error if the table is a view

patch by Benjamin Lerer; reviewed by Aleksey Yeschenko  for CASSANDRA-10361


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

Branch: refs/heads/trunk
Commit: caadcf69ee3160458db0eae9e3810127709b3717
Parents: a90de7c
Author: blerer <be...@datastax.com>
Authored: Thu Sep 17 21:42:15 2015 +0200
Committer: blerer <be...@datastax.com>
Committed: Thu Sep 17 21:42:15 2015 +0200

----------------------------------------------------------------------
 .../cql3/statements/DropTableStatement.java     |  2 +-
 .../org/apache/cassandra/cql3/ViewTest.java     | 50 ++++++++++++++++----
 2 files changed, 42 insertions(+), 10 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cassandra/blob/caadcf69/src/java/org/apache/cassandra/cql3/statements/DropTableStatement.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/cql3/statements/DropTableStatement.java b/src/java/org/apache/cassandra/cql3/statements/DropTableStatement.java
index 14d89d9..1f61020 100644
--- a/src/java/org/apache/cassandra/cql3/statements/DropTableStatement.java
+++ b/src/java/org/apache/cassandra/cql3/statements/DropTableStatement.java
@@ -63,7 +63,7 @@ public class DropTableStatement extends SchemaAlteringStatement
         try
         {
             KeyspaceMetadata ksm = Schema.instance.getKSMetaData(keyspace());
-            CFMetaData cfm = ksm.tables.getNullable(columnFamily());
+            CFMetaData cfm = ksm.getTableOrViewNullable(columnFamily());
             if (cfm != null)
             {
                 if (cfm.isView())

http://git-wip-us.apache.org/repos/asf/cassandra/blob/caadcf69/test/unit/org/apache/cassandra/cql3/ViewTest.java
----------------------------------------------------------------------
diff --git a/test/unit/org/apache/cassandra/cql3/ViewTest.java b/test/unit/org/apache/cassandra/cql3/ViewTest.java
index 9c47707..95662e5 100644
--- a/test/unit/org/apache/cassandra/cql3/ViewTest.java
+++ b/test/unit/org/apache/cassandra/cql3/ViewTest.java
@@ -22,18 +22,16 @@ import java.math.BigDecimal;
 import java.math.BigInteger;
 import java.net.InetAddress;
 import java.text.SimpleDateFormat;
-import java.util.*;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Date;
+import java.util.HashSet;
+import java.util.List;
+import java.util.UUID;
 import java.util.concurrent.TimeUnit;
 
-import org.junit.After;
-import org.junit.Before;
-import org.junit.BeforeClass;
-import org.junit.Test;
-
-import com.datastax.driver.core.*;
-import com.datastax.driver.core.ResultSet;
-import com.datastax.driver.core.exceptions.InvalidQueryException;
 import junit.framework.Assert;
+
 import org.apache.cassandra.concurrent.SEPExecutor;
 import org.apache.cassandra.concurrent.Stage;
 import org.apache.cassandra.concurrent.StageManager;
@@ -46,6 +44,14 @@ import org.apache.cassandra.serializers.SimpleDateSerializer;
 import org.apache.cassandra.serializers.TimeSerializer;
 import org.apache.cassandra.utils.ByteBufferUtil;
 import org.apache.cassandra.utils.FBUtilities;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+import com.datastax.driver.core.ResultSet;
+import com.datastax.driver.core.Row;
+import com.datastax.driver.core.exceptions.InvalidQueryException;
 
 public class ViewTest extends CQLTester
 {
@@ -1352,4 +1358,30 @@ public class ViewTest extends CQLTester
                       row(2),
                       row(1));
     }
+
+    @Test
+    public void testDropTableWithMV() throws Throwable
+    {
+        createTable("CREATE TABLE %s (" +
+                "a int," +
+                "b int," +
+                "c int," +
+                "d int," +
+                "PRIMARY KEY (a, b, c))");
+
+        executeNet(protocolVersion, "USE " + keyspace());
+
+        createView(keyspace() + ".mv1",
+                   "CREATE MATERIALIZED VIEW %s AS SELECT * FROM %%s WHERE b IS NOT NULL AND c IS NOT NULL PRIMARY KEY (a, b, c)");
+
+        try
+        {
+            executeNet(protocolVersion, "DROP TABLE " + keyspace() + ".mv1");
+            Assert.fail();
+        }
+        catch (InvalidQueryException e)
+        {
+            Assert.assertEquals("Cannot use DROP TABLE on Materialized View", e.getMessage());
+        }
+    }
 }