cassandra-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From ble...@apache.org
Subject [3/3] cassandra git commit: Merge branch cassandra-2.2 into cassandra-3.0
Date Tue, 20 Oct 2015 12:11:05 GMT
Merge branch 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/a8807391
Tree: http://git-wip-us.apache.org/repos/asf/cassandra/tree/a8807391
Diff: http://git-wip-us.apache.org/repos/asf/cassandra/diff/a8807391

Branch: refs/heads/cassandra-3.0
Commit: a880739187ea5521e8e558a19871985a846b330e
Parents: fa909cc a337907
Author: blerer <benjamin.lerer@datastax.com>
Authored: Tue Oct 20 14:09:16 2015 +0200
Committer: blerer <benjamin.lerer@datastax.com>
Committed: Tue Oct 20 14:10:15 2015 +0200

----------------------------------------------------------------------
 CHANGES.txt                                     |  1 +
 pylib/cqlshlib/cql3handling.py                  |  4 ++--
 .../org/apache/cassandra/cql3/Operations.java   | 16 ++++++++++++-
 .../cql3/statements/DeleteStatement.java        |  7 +++---
 .../cql3/statements/ModificationStatement.java  | 21 +++++++++-------
 .../cql3/statements/UpdateStatement.java        | 25 ++++++++++----------
 .../operations/InsertUpdateIfConditionTest.java | 11 +++++++++
 7 files changed, 57 insertions(+), 28 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cassandra/blob/a8807391/CHANGES.txt
----------------------------------------------------------------------
diff --cc CHANGES.txt
index 5a118ca,261a53a..25ad1fb
--- a/CHANGES.txt
+++ b/CHANGES.txt
@@@ -1,34 -1,19 +1,35 @@@
 -2.2.4
 +3.0
 +Merged from 2.2:
   * Expose phi values from failure detector via JMX and tweak debug
     and trace logging (CASSANDRA-9526)
 - * Fix RangeNamesQueryPager (CASSANDRA-10509)
 - * Deprecate Pig support (CASSANDRA-10542)
 - * Reduce contention getting instances of CompositeType (CASSANDRA-10433)
  Merged from 2.1:
+  * Fix conditions on static columns (CASSANDRA-10264)
   * AssertionError: attempted to delete non-existing file CommitLog (CASSANDRA-10377)
 - * (cqlsh) Distinguish negative and positive infinity in output (CASSANDRA-10523)
 - * (cqlsh) allow custom time_format for COPY TO (CASSANDRA-8970)
 - * Don't allow startup if the node's rack has changed (CASSANDRA-10242)
 - * (cqlsh) show partial trace if incomplete after max_trace_wait (CASSANDRA-7645)
  
  
 -2.2.3
 +3.0-rc2
 + * Fix SELECT DISTINCT queries between 2.2.2 nodes and 3.0 nodes (CASSANDRA-10473)
 + * Remove circular references in SegmentedFile (CASSANDRA-10543)
 + * Ensure validation of indexed values only occurs once per-partition (CASSANDRA-10536)
 + * Fix handling of static columns for range tombstones in thrift (CASSANDRA-10174)
 + * Support empty ColumnFilter for backward compatility on empty IN (CASSANDRA-10471)
 + * Remove Pig support (CASSANDRA-10542)
 + * Fix LogFile throws Exception when assertion is disabled (CASSANDRA-10522)
 + * Revert CASSANDRA-7486, make CMS default GC, move GC config to
 +   conf/jvm.options (CASSANDRA-10403)
 + * Fix TeeingAppender causing some logs to be truncated/empty (CASSANDRA-10447)
 + * Allow EACH_QUORUM for reads (CASSANDRA-9602)
 + * Fix potential ClassCastException while upgrading (CASSANDRA-10468)
 + * Fix NPE in MVs on update (CASSANDRA-10503)
 + * Only include modified cell data in indexing deltas (CASSANDRA-10438)
 + * Do not load keyspace when creating sstable writer (CASSANDRA-10443)
 + * If node is not yet gossiping write all MV updates to batchlog only (CASSANDRA-10413)
 + * Re-populate token metadata after commit log recovery (CASSANDRA-10293)
 + * Provide additional metrics for materialized views (CASSANDRA-10323)
 + * Flush system schema tables after local schema changes (CASSANDRA-10429)
 +Merged from 2.2:
 + * Reduce contention getting instances of CompositeType (CASSANDRA-10433)
 + * Fix the regression when using LIMIT with aggregates (CASSANDRA-10487)
   * Avoid NoClassDefFoundError during DataDescriptor initialization on windows (CASSANDRA-10412)
   * Preserve case of quoted Role & User names (CASSANDRA-10394)
   * cqlsh pg-style-strings broken (CASSANDRA-10484)

http://git-wip-us.apache.org/repos/asf/cassandra/blob/a8807391/pylib/cqlshlib/cql3handling.py
----------------------------------------------------------------------
diff --cc pylib/cqlshlib/cql3handling.py
index 1398e0d,b4edac1..42e542f
--- a/pylib/cqlshlib/cql3handling.py
+++ b/pylib/cqlshlib/cql3handling.py
@@@ -894,7 -874,7 +894,7 @@@ syntax_rules += r''
                 ;
  <conditions> ::=  <condition> ( "AND" <condition> )*
                 ;
--<condition> ::= <cident> ( "[" <term> "]" )? ( ( "=" | "<" | ">"
| "<=" | ">=" | "!=" ) <term>
++<condition> ::= <cident> ( "[" <term> "]" )? (("=" | "<" | ">" |
"<=" | ">=" | "!=") <term>
                                               | "IN" "(" <term> ( "," <term>
)* ")")
                ;
  '''

http://git-wip-us.apache.org/repos/asf/cassandra/blob/a8807391/src/java/org/apache/cassandra/cql3/Operations.java
----------------------------------------------------------------------
diff --cc src/java/org/apache/cassandra/cql3/Operations.java
index c4cade1,0000000..0ef8517
mode 100644,000000..100644
--- a/src/java/org/apache/cassandra/cql3/Operations.java
+++ b/src/java/org/apache/cassandra/cql3/Operations.java
@@@ -1,135 -1,0 +1,149 @@@
 +/*
 + * 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 java.util.ArrayList;
 +import java.util.Iterator;
 +import java.util.List;
 +
 +import org.apache.cassandra.cql3.functions.Function;
++import org.apache.cassandra.cql3.statements.StatementType;
 +
 +import com.google.common.collect.Iterables;
 +import com.google.common.collect.Iterators;
 +
 +/**
 + * A set of <code>Operation</code>s.
 + *
 + */
 +public final class Operations implements Iterable<Operation>
 +{
 +    /**
++     * The type of statement.
++     */
++    private final StatementType type;
++
++    /**
 +     * The operations on regular columns.
 +     */
 +    private final List<Operation> regularOperations = new ArrayList<>();
 +
 +    /**
 +     * The operations on static columns.
 +     */
 +    private final List<Operation> staticOperations = new ArrayList<>();
 +
++    public Operations(StatementType type)
++    {
++        this.type = type;
++    }
++
 +    /**
 +     * Checks if some of the operations apply to static columns.
 +     *
 +     * @return <code>true</code> if some of the operations apply to static columns,
<code>false</code> otherwise.
 +     */
 +    public boolean appliesToStaticColumns()
 +    {
 +        return !staticOperations.isEmpty();
 +    }
 +
 +    /**
 +     * Checks if some of the operations apply to regular columns.
 +     *
 +     * @return <code>true</code> if some of the operations apply to regular
columns, <code>false</code> otherwise.
 +     */
 +    public boolean appliesToRegularColumns()
 +    {
-         return !regularOperations.isEmpty();
++     // If we have regular operations, this applies to regular columns.
++        // Otherwise, if the statement is a DELETE and staticOperations is also empty, this
means we have no operations,
++        // which for a DELETE means a full row deletion. Which means the operation applies
to all columns and regular ones in particular.
++        return !regularOperations.isEmpty() || (type.isDelete() && staticOperations.isEmpty());
 +    }
 +
 +    /**
 +     * Returns the operation on regular columns.
 +     * @return the operation on regular columns
 +     */
 +    public List<Operation> regularOperations()
 +    {
 +        return regularOperations;
 +    }
 +
 +    /**
 +     * Returns the operation on static columns.
 +     * @return the operation on static columns
 +     */
 +    public List<Operation> staticOperations()
 +    {
 +        return staticOperations;
 +    }
 +
 +    /**
 +     * Adds the specified <code>Operation</code> to this set of operations.
 +     * @param operation the operation to add
 +     */
 +    public void add(Operation operation)
 +    {
 +        if (operation.column.isStatic())
 +            staticOperations.add(operation);
 +        else
 +            regularOperations.add(operation);
 +    }
 +
 +    /**
 +     * Checks if one of the operations requires a read.
 +     *
 +     * @return <code>true</code> if one of the operations requires a read, <code>false</code>
otherwise.
 +     */
 +    public boolean requiresRead()
 +    {
 +        // Lists SET operation incurs a read.
 +        for (Operation operation : this)
 +            if (operation.requiresRead())
 +                return true;
 +
 +        return false;
 +    }
 +
 +    /**
 +     * Checks if this <code>Operations</code> is empty.
 +     * @return <code>true</code> if this <code>Operations</code>
is empty, <code>false</code> otherwise.
 +     */
 +    public boolean isEmpty()
 +    {
 +        return staticOperations.isEmpty() && regularOperations.isEmpty();
 +    }
 +
 +    /**
 +     * {@inheritDoc}
 +     */
 +    @Override
 +    public Iterator<Operation> iterator()
 +    {
 +        return Iterators.concat(staticOperations.iterator(), regularOperations.iterator());
 +    }
 +
 +    public Iterable<? extends Function> getFunctions()
 +    {
 +        List<Function> functions = new ArrayList<>();
 +        for (Operation operation : this)
 +            Iterables.addAll(functions, operation.getFunctions());
 +        return functions;
 +    }
 +}

http://git-wip-us.apache.org/repos/asf/cassandra/blob/a8807391/src/java/org/apache/cassandra/cql3/statements/DeleteStatement.java
----------------------------------------------------------------------
diff --cc src/java/org/apache/cassandra/cql3/statements/DeleteStatement.java
index d51f261,ff685cf..0efe35c
--- a/src/java/org/apache/cassandra/cql3/statements/DeleteStatement.java
+++ b/src/java/org/apache/cassandra/cql3/statements/DeleteStatement.java
@@@ -119,19 -116,14 +119,19 @@@ public class DeleteStatement extends Mo
                        List<Pair<ColumnIdentifier.Raw, ColumnCondition.Raw>>
conditions,
                        boolean ifExists)
          {
--            super(name, attrs, conditions, false, ifExists);
++            super(name, StatementType.DELETE, attrs, conditions, false, ifExists);
              this.deletions = deletions;
              this.whereClause = whereClause;
          }
  
 -        protected ModificationStatement prepareInternal(CFMetaData cfm, VariableSpecifications
boundNames, Attributes attrs) throws InvalidRequestException
 +
 +        @Override
 +        protected ModificationStatement prepareInternal(CFMetaData cfm,
 +                                                        VariableSpecifications boundNames,
 +                                                        Conditions conditions,
 +                                                        Attributes attrs)
          {
-             Operations operations = new Operations();
 -            DeleteStatement stmt = new DeleteStatement(ModificationStatement.StatementType.DELETE,
boundNames.size(), cfm, attrs);
++            Operations operations = new Operations(type);
  
              for (Operation.RawDeletion deletion : deletions)
              {
@@@ -143,27 -139,10 +143,26 @@@
  
                  Operation op = deletion.prepare(cfm.ksName, def);
                  op.collectMarkerSpecification(boundNames);
 -                stmt.addOperation(op);
 +                operations.add(op);
              }
  
-             StatementRestrictions restrictions = newRestrictions(StatementType.DELETE,
-                                                                  cfm,
 -            stmt.processWhereClause(whereClause, boundNames);
++            StatementRestrictions restrictions = newRestrictions(cfm,
 +                                                                 boundNames,
 +                                                                 operations,
 +                                                                 whereClause,
 +                                                                 conditions);
 +
 +            DeleteStatement stmt = new DeleteStatement(boundNames.size(),
 +                                                       cfm,
 +                                                       operations,
 +                                                       restrictions,
 +                                                       conditions,
 +                                                       attrs);
 +
 +            if (stmt.hasConditions())
 +                checkTrue(restrictions.hasAllPKColumnsRestrictedByEqualities(),
 +                          "DELETE statements must restrict all PRIMARY KEY columns with
equality relations" +
 +                          " in order to use IF conditions");
              return stmt;
          }
      }

http://git-wip-us.apache.org/repos/asf/cassandra/blob/a8807391/src/java/org/apache/cassandra/cql3/statements/ModificationStatement.java
----------------------------------------------------------------------
diff --cc src/java/org/apache/cassandra/cql3/statements/ModificationStatement.java
index 0e989e6,8b594dd..1ea1e4d
--- a/src/java/org/apache/cassandra/cql3/statements/ModificationStatement.java
+++ b/src/java/org/apache/cassandra/cql3/statements/ModificationStatement.java
@@@ -734,14 -748,14 +734,21 @@@ public abstract class ModificationState
  
      public static abstract class Parsed extends CFStatement
      {
 -        protected final Attributes.Raw attrs;
 -        protected final List<Pair<ColumnIdentifier.Raw, ColumnCondition.Raw>>
conditions;
++        protected final StatementType type;
 +        private final Attributes.Raw attrs;
 +        private final List<Pair<ColumnIdentifier.Raw, ColumnCondition.Raw>>
conditions;
          private final boolean ifNotExists;
          private final boolean ifExists;
  
--        protected Parsed(CFName name, Attributes.Raw attrs, List<Pair<ColumnIdentifier.Raw,
ColumnCondition.Raw>> conditions, boolean ifNotExists, boolean ifExists)
++        protected Parsed(CFName name,
++                         StatementType type,
++                         Attributes.Raw attrs,
++                         List<Pair<ColumnIdentifier.Raw, ColumnCondition.Raw>>
conditions,
++                         boolean ifNotExists,
++                         boolean ifExists)
          {
              super(name);
++            this.type = type;
              this.attrs = attrs;
              this.conditions = conditions == null ? Collections.<Pair<ColumnIdentifier.Raw,
ColumnCondition.Raw>>emptyList() : conditions;
              this.ifNotExists = ifNotExists;
@@@ -763,114 -777,59 +770,112 @@@
              Attributes preparedAttributes = attrs.prepare(keyspace(), columnFamily());
              preparedAttributes.collectMarkerSpecification(boundNames);
  
 -            ModificationStatement stmt = prepareInternal(metadata, boundNames, preparedAttributes);
 +            Conditions preparedConditions = prepareConditions(metadata, boundNames);
  
 -            if (ifNotExists || ifExists || !conditions.isEmpty())
 +            return prepareInternal(metadata,
 +                                   boundNames,
 +                                   preparedConditions,
 +                                   preparedAttributes);
 +        }
 +
 +        /**
 +         * Returns the column conditions.
 +         *
 +         * @param metadata the column family meta data
 +         * @param boundNames the bound names
 +         * @return the column conditions.
 +         */
 +        private Conditions prepareConditions(CFMetaData metadata, VariableSpecifications
boundNames)
 +        {
 +            // To have both 'IF EXISTS'/'IF NOT EXISTS' and some other conditions doesn't
make sense.
 +            // So far this is enforced by the parser, but let's assert it for sanity if
ever the parse changes.
 +            if (ifExists)
              {
 -                if (stmt.isCounter())
 -                    throw new InvalidRequestException("Conditional updates are not supported
on counter tables");
 +                assert conditions.isEmpty();
 +                assert !ifNotExists;
 +                return Conditions.IF_EXISTS_CONDITION;
 +            }
  
 -                if (attrs.timestamp != null)
 -                    throw new InvalidRequestException("Cannot provide custom timestamp for
conditional updates");
 +            if (ifNotExists)
 +            {
 +                assert conditions.isEmpty();
 +                assert !ifExists;
 +                return Conditions.IF_NOT_EXISTS_CONDITION;
 +            }
  
 -                if (ifNotExists)
 -                {
 -                    // To have both 'IF NOT EXISTS' and some other conditions doesn't make
sense.
 -                    // So far this is enforced by the parser, but let's assert it for sanity
if ever the parse changes.
 -                    assert conditions.isEmpty();
 -                    assert !ifExists;
 -                    stmt.setIfNotExistCondition();
 -                }
 -                else if (ifExists)
 -                {
 -                    assert conditions.isEmpty();
 -                    assert !ifNotExists;
 -                    stmt.setIfExistCondition();
 -                }
 -                else
 -                {
 -                    for (Pair<ColumnIdentifier.Raw, ColumnCondition.Raw> entry : conditions)
 -                    {
 -                        ColumnIdentifier id = entry.left.prepare(metadata);
 -                        ColumnDefinition def = metadata.getColumnDefinition(id);
 -                        if (def == null)
 -                            throw new InvalidRequestException(String.format("Unknown identifier
%s", id));
 -
 -                        ColumnCondition condition = entry.right.prepare(keyspace(), def);
 -                        condition.collectMarkerSpecification(boundNames);
 -
 -                        switch (def.kind)
 -                        {
 -                            case PARTITION_KEY:
 -                            case CLUSTERING_COLUMN:
 -                                throw new InvalidRequestException(String.format("PRIMARY
KEY column '%s' cannot have IF conditions", id));
 -                            default:
 -                                stmt.addCondition(condition);
 -                                break;
 -                        }
 -                    }
 -                }
 +            if (conditions.isEmpty())
 +                return Conditions.EMPTY_CONDITION;
 +
 +            return prepareColumnConditions(metadata, boundNames);
 +        }
 +
 +        /**
 +         * Returns the column conditions.
 +         *
 +         * @param metadata the column family meta data
 +         * @param boundNames the bound names
 +         * @return the column conditions.
 +         */
 +        private ColumnConditions prepareColumnConditions(CFMetaData metadata, VariableSpecifications
boundNames)
 +        {
 +            checkNull(attrs.timestamp, "Cannot provide custom timestamp for conditional
updates");
 +
 +            ColumnConditions.Builder builder = ColumnConditions.newBuilder();
 +
 +            for (Pair<ColumnIdentifier.Raw, ColumnCondition.Raw> entry : conditions)
 +            {
 +                ColumnIdentifier id = entry.left.prepare(metadata);
 +                ColumnDefinition def = metadata.getColumnDefinition(id);
 +                checkNotNull(metadata.getColumnDefinition(id), "Unknown identifier %s in
IF conditions", id);
 +
 +                ColumnCondition condition = entry.right.prepare(keyspace(), def);
 +                condition.collectMarkerSpecification(boundNames);
  
 -                stmt.validateWhereClauseForConditions();
 +                checkFalse(def.isPrimaryKeyColumn(), "PRIMARY KEY column '%s' cannot have
IF conditions", id);
 +                builder.add(condition);
              }
 -            return stmt;
 +            return builder.build();
          }
  
 -        protected abstract ModificationStatement prepareInternal(CFMetaData cfm, VariableSpecifications
boundNames, Attributes attrs) throws InvalidRequestException;
 +        protected abstract ModificationStatement prepareInternal(CFMetaData cfm,
 +                                                                 VariableSpecifications
boundNames,
 +                                                                 Conditions conditions,
 +                                                                 Attributes attrs);
 +
 +        /**
 +         * Creates the restrictions.
 +         *
-          * @param type the statement type
 +         * @param cfm the column family meta data
 +         * @param boundNames the bound names
 +         * @param operations the column operations
 +         * @param where the where clause
 +         * @param conditions the conditions
 +         * @return the restrictions
 +         */
-         protected static StatementRestrictions newRestrictions(StatementType type,
-                                                                CFMetaData cfm,
-                                                                VariableSpecifications boundNames,
-                                                                Operations operations,
-                                                                WhereClause where,
-                                                                Conditions conditions)
++        protected StatementRestrictions newRestrictions(CFMetaData cfm,
++                                                        VariableSpecifications boundNames,
++                                                        Operations operations,
++                                                        WhereClause where,
++                                                        Conditions conditions)
 +        {
 +            if (where.containsCustomExpressions())
 +                throw new InvalidRequestException(CUSTOM_EXPRESSIONS_NOT_ALLOWED);
 +
 +            boolean applyOnlyToStaticColumns = appliesOnlyToStaticColumns(operations, conditions);
 +            return new StatementRestrictions(type, cfm, where, boundNames, applyOnlyToStaticColumns,
false, false, false);
 +        }
 +
 +        /**
 +         * Retrieves the <code>ColumnDefinition</code> corresponding to the
specified raw <code>ColumnIdentifier</code>.
 +         *
 +         * @param cfm the column family meta data
 +         * @param rawId the raw <code>ColumnIdentifier</code>
 +         * @return the <code>ColumnDefinition</code> corresponding to the specified
raw <code>ColumnIdentifier</code>
 +         */
 +        protected static ColumnDefinition getColumnDefinition(CFMetaData cfm, Raw rawId)
 +        {
 +            ColumnIdentifier id = rawId.prepare(cfm);
 +            return checkNotNull(cfm.getColumnDefinition(id), "Unknown identifier %s", id);
 +        }
      }
  }

http://git-wip-us.apache.org/repos/asf/cassandra/blob/a8807391/src/java/org/apache/cassandra/cql3/statements/UpdateStatement.java
----------------------------------------------------------------------
diff --cc src/java/org/apache/cassandra/cql3/statements/UpdateStatement.java
index d6d0266,ad46a0f..6f872d4
--- a/src/java/org/apache/cassandra/cql3/statements/UpdateStatement.java
+++ b/src/java/org/apache/cassandra/cql3/statements/UpdateStatement.java
@@@ -131,42 -166,47 +131,42 @@@ public class UpdateStatement extends Mo
                              List<Term.Raw> columnValues,
                              boolean ifNotExists)
          {
--            super(name, attrs, null, ifNotExists, false);
++            super(name, StatementType.INSERT, attrs, null, ifNotExists, false);
              this.columnNames = columnNames;
              this.columnValues = columnValues;
          }
  
 -        protected ModificationStatement prepareInternal(CFMetaData cfm, VariableSpecifications
boundNames, Attributes attrs) throws InvalidRequestException
 +        @Override
 +        protected ModificationStatement prepareInternal(CFMetaData cfm,
 +                                                        VariableSpecifications boundNames,
 +                                                        Conditions conditions,
 +                                                        Attributes attrs)
          {
 -            UpdateStatement stmt = new UpdateStatement(ModificationStatement.StatementType.INSERT,
boundNames.size(), cfm, attrs);
  
              // Created from an INSERT
 -            if (stmt.isCounter())
 -                throw new InvalidRequestException("INSERT statements are not allowed on
counter tables, use UPDATE instead");
 +            checkFalse(cfm.isCounter(), "INSERT statements are not allowed on counter tables,
use UPDATE instead");
  
 -            if (columnNames == null)
 -                throw new InvalidRequestException("Column names for INSERT must be provided
when using VALUES");
 -            if (columnNames.isEmpty())
 -                throw new InvalidRequestException("No columns provided to INSERT");
 -            if (columnNames.size() != columnValues.size())
 -                throw new InvalidRequestException("Unmatched column names/values");
 +            checkFalse(columnNames == null, "Column names for INSERT must be provided when
using VALUES");
 +            checkFalse(columnNames.isEmpty(), "No columns provided to INSERT");
 +            checkFalse(columnNames.size() != columnValues.size(), "Unmatched column names/values");
 +            checkContainsNoDuplicates(columnNames, "The column names contains duplicates");
 +
 +            WhereClause.Builder whereClause = new WhereClause.Builder();
-             Operations operations = new Operations();
++            Operations operations = new Operations(type);
 +            boolean hasClusteringColumnsSet = false;
  
 -            String ks = keyspace();
              for (int i = 0; i < columnNames.size(); i++)
              {
 -                ColumnIdentifier id = columnNames.get(i).prepare(cfm);
 -                ColumnDefinition def = cfm.getColumnDefinition(id);
 -                if (def == null)
 -                    throw new InvalidRequestException(String.format("Unknown identifier
%s", id));
 +                ColumnDefinition def = getColumnDefinition(cfm, columnNames.get(i));
  
 -                for (int j = 0; j < i; j++)
 -                {
 -                    ColumnIdentifier otherId = columnNames.get(j).prepare(cfm);
 -                    if (id.equals(otherId))
 -                        throw new InvalidRequestException(String.format("Multiple definitions
found for column %s", id));
 -                }
 +                if (def.isClusteringColumn())
 +                    hasClusteringColumnsSet = true;
  
                  Term.Raw value = columnValues.get(i);
 +
                  if (def.isPrimaryKeyColumn())
                  {
 -                    Term t = value.prepare(ks, def);
 -                    t.collectMarkerSpecification(boundNames);
 -                    stmt.addKeyValue(def, t);
 +                    whereClause.add(new SingleColumnRelation(columnNames.get(i), Operator.EQ,
value));
                  }
                  else
                  {
@@@ -176,24 -216,7 +176,24 @@@
                  }
              }
  
 -            return stmt;
 +            boolean applyOnlyToStaticColumns = appliesOnlyToStaticColumns(operations, conditions)
&& !hasClusteringColumnsSet;
 +
-             StatementRestrictions restrictions = new StatementRestrictions(StatementType.INSERT,
++            StatementRestrictions restrictions = new StatementRestrictions(type,
 +                                                                           cfm,
 +                                                                           whereClause.build(),
 +                                                                           boundNames,
 +                                                                           applyOnlyToStaticColumns,
 +                                                                           false,
 +                                                                           false,
 +                                                                           false);
 +
-             return new UpdateStatement(StatementType.INSERT,
++            return new UpdateStatement(type,
 +                                       boundNames.size(),
 +                                       cfm,
 +                                       operations,
 +                                       restrictions,
 +                                       conditions,
 +                                       attrs);
          }
      }
  
@@@ -206,7 -229,7 +206,7 @@@
  
          public ParsedInsertJson(CFName name, Attributes.Raw attrs, Json.Raw jsonValue, boolean
ifNotExists)
          {
--            super(name, attrs, null, ifNotExists, false);
++            super(name, StatementType.INSERT, attrs, null, ifNotExists, false);
              this.jsonValue = jsonValue;
          }
  
@@@ -221,48 -242,15 +221,48 @@@
              Collection<ColumnDefinition> defs = cfm.allColumns();
              Json.Prepared prepared = jsonValue.prepareAndCollectMarkers(cfm, defs, boundNames);
  
 +            WhereClause.Builder whereClause = new WhereClause.Builder();
-             Operations operations = new Operations();
++            Operations operations = new Operations(type);
 +            boolean hasClusteringColumnsSet = false;
 +
              for (ColumnDefinition def : defs)
              {
 +                if (def.isClusteringColumn())
 +                    hasClusteringColumnsSet = true;
 +
 +                Term.Raw raw = prepared.getRawTermForColumn(def);
                  if (def.isPrimaryKeyColumn())
 -                    stmt.addKeyValue(def, prepared.getPrimaryKeyValueForColumn(def));
 +                {
 +                    whereClause.add(new SingleColumnRelation(new ColumnIdentifier.ColumnIdentifierValue(def.name),
 +                                                             Operator.EQ,
 +                                                             raw));
 +                }
                  else
 -                    stmt.addOperation(prepared.getSetOperationForColumn(def));
 +                {
 +                    Operation operation = new Operation.SetValue(raw).prepare(keyspace(),
def);
 +                    operation.collectMarkerSpecification(boundNames);
 +                    operations.add(operation);
 +                }
              }
  
 -            return stmt;
 +            boolean applyOnlyToStaticColumns = appliesOnlyToStaticColumns(operations, conditions)
&& !hasClusteringColumnsSet;
 +
-             StatementRestrictions restrictions = new StatementRestrictions(StatementType.INSERT,
++            StatementRestrictions restrictions = new StatementRestrictions(type,
 +                                                                           cfm,
 +                                                                           whereClause.build(),
 +                                                                           boundNames,
 +                                                                           applyOnlyToStaticColumns,
 +                                                                           false,
 +                                                                           false,
 +                                                                           false);
 +
-             return new UpdateStatement(StatementType.INSERT,
++            return new UpdateStatement(type,
 +                                       boundNames.size(),
 +                                       cfm,
 +                                       operations,
 +                                       restrictions,
 +                                       conditions,
 +                                       attrs);
          }
      }
  
@@@ -289,18 -277,14 +289,18 @@@
                              List<Pair<ColumnIdentifier.Raw, ColumnCondition.Raw>>
conditions,
                              boolean ifExists)
          {
--            super(name, attrs, conditions, false, ifExists);
++            super(name, StatementType.UPDATE, attrs, conditions, false, ifExists);
              this.updates = updates;
              this.whereClause = whereClause;
          }
  
 -        protected ModificationStatement prepareInternal(CFMetaData cfm, VariableSpecifications
boundNames, Attributes attrs) throws InvalidRequestException
 +        @Override
 +        protected ModificationStatement prepareInternal(CFMetaData cfm,
 +                                                        VariableSpecifications boundNames,
 +                                                        Conditions conditions,
 +                                                        Attributes attrs)
          {
-             Operations operations = new Operations();
 -            UpdateStatement stmt = new UpdateStatement(ModificationStatement.StatementType.UPDATE,
boundNames.size(), cfm, attrs);
++            Operations operations = new Operations(type);
  
              for (Pair<ColumnIdentifier.Raw, Operation.RawUpdate> entry : updates)
              {
@@@ -310,23 -294,20 +310,22 @@@
  
                  Operation operation = entry.right.prepare(keyspace(), def);
                  operation.collectMarkerSpecification(boundNames);
 -
 -                switch (def.kind)
 -                {
 -                    case PARTITION_KEY:
 -                    case CLUSTERING_COLUMN:
 -                        throw new InvalidRequestException(String.format("PRIMARY KEY part
%s found in SET part", entry.left));
 -                    default:
 -                        stmt.addOperation(operation);
 -                        break;
 -                }
 +                operations.add(operation);
              }
  
-             StatementRestrictions restrictions = newRestrictions(StatementType.UPDATE,
-                                                                  cfm,
 -            stmt.processWhereClause(whereClause, boundNames);
 -            return stmt;
++            StatementRestrictions restrictions = newRestrictions(cfm,
 +                                                                 boundNames,
 +                                                                 operations,
 +                                                                 whereClause,
 +                                                                 conditions);
 +
-             return new UpdateStatement(StatementType.UPDATE,
++            return new UpdateStatement(type,
 +                                       boundNames.size(),
 +                                       cfm,
 +                                       operations,
 +                                       restrictions,
 +                                       conditions,
 +                                       attrs);
          }
      }
  }

http://git-wip-us.apache.org/repos/asf/cassandra/blob/a8807391/test/unit/org/apache/cassandra/cql3/validation/operations/InsertUpdateIfConditionTest.java
----------------------------------------------------------------------
diff --cc test/unit/org/apache/cassandra/cql3/validation/operations/InsertUpdateIfConditionTest.java
index 9cde6d7,b73ecdf..ade80bb
--- a/test/unit/org/apache/cassandra/cql3/validation/operations/InsertUpdateIfConditionTest.java
+++ b/test/unit/org/apache/cassandra/cql3/validation/operations/InsertUpdateIfConditionTest.java
@@@ -188,25 -175,22 +188,36 @@@ public class InsertUpdateIfConditionTes
          assertRows(execute("DELETE FROM %s WHERE k='k' AND i=0 IF EXISTS"), row(false));
  
          // CASSANDRA-6430
 -        assertInvalid("DELETE FROM %s WHERE k = 'k' IF EXISTS");
 -        assertInvalid("DELETE FROM %s WHERE k = 'k' IF v = 'foo'");
 -        assertInvalid("DELETE FROM %s WHERE i = 0 IF EXISTS");
 -        assertInvalid("DELETE FROM %s WHERE k = 0 AND i > 0 IF EXISTS");
 -        assertInvalid("DELETE FROM %s WHERE k = 0 AND i > 0 IF v = 'foo'");
 +        assertInvalidMessage("DELETE statements must restrict all PRIMARY KEY columns with
equality relations in order to use IF conditions",
 +                             "DELETE FROM %s WHERE k = 'k' IF EXISTS");
 +        assertInvalidMessage("DELETE statements must restrict all PRIMARY KEY columns with
equality relations in order to use IF conditions",
 +                             "DELETE FROM %s WHERE k = 'k' IF v = 'foo'");
 +        assertInvalidMessage("Some partition key parts are missing: k",
 +                             "DELETE FROM %s WHERE i = 0 IF EXISTS");
 +
 +        assertInvalidMessage("Invalid INTEGER constant (0) for \"k\" of type text",
 +                             "DELETE FROM %s WHERE k = 0 AND i > 0 IF EXISTS");
 +        assertInvalidMessage("Invalid INTEGER constant (0) for \"k\" of type text",
 +                             "DELETE FROM %s WHERE k = 0 AND i > 0 IF v = 'foo'");
 +        assertInvalidMessage("DELETE statements must restrict all PRIMARY KEY columns with
equality relations in order to use IF conditions",
 +                             "DELETE FROM %s WHERE k = 'k' AND i > 0 IF EXISTS");
 +        assertInvalidMessage("DELETE statements must restrict all PRIMARY KEY columns with
equality relations in order to use IF conditions",
 +                             "DELETE FROM %s WHERE k = 'k' AND i > 0 IF v = 'foo'");
 +        assertInvalidMessage("IN on the clustering key columns is not supported with conditional
deletions",
 +                             "DELETE FROM %s WHERE k = 'k' AND i IN (0, 1) IF v = 'foo'");
 +        assertInvalidMessage("IN on the clustering key columns is not supported with conditional
deletions",
 +                             "DELETE FROM %s WHERE k = 'k' AND i IN (0, 1) IF EXISTS");
+ 
+         createTable("CREATE TABLE %s(k int, s int static, i int, v text, PRIMARY KEY(k,
i))");
+         execute("INSERT INTO %s (k, s, i, v) VALUES ( 1, 1, 2, '1')");
+         assertRows(execute("DELETE v FROM %s WHERE k = 1 AND i = 2 IF s != 1"), row(false,
1));
+         assertRows(execute("DELETE v FROM %s WHERE k = 1 AND i = 2 IF s = 1"), row(true));
+         assertRows(execute("SELECT * FROM %s WHERE k = 1 AND i = 2"), row(1, 2, 1, null));
+ 
+         assertRows(execute("DELETE FROM %s WHERE  k = 1 AND i = 2 IF s != 1"), row(false,
1));
+         assertRows(execute("DELETE FROM %s WHERE k = 1 AND i = 2 IF s = 1"), row(true));
+         assertEmpty(execute("SELECT * FROM %s WHERE k = 1 AND i = 2"));
+         assertRows(execute("SELECT * FROM %s WHERE k = 1"), row(1, null, 1, null));
      }
  
      /**


Mime
View raw message