Merge branch 'cassandra-3.11' into trunk

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

Branch: refs/heads/trunk
Commit: de60cf0759e9721ddd1aab725c511a8f910cf415
Parents: 2842716 99196cb
Author: Jeff Jirsa <jji...@apple.com>
Authored: Mon Jul 31 15:30:10 2017 -0700
Committer: Jeff Jirsa <jji...@apple.com>
Committed: Mon Jul 31 15:30:54 2017 -0700

----------------------------------------------------------------------
 CHANGES.txt                                     |  1 +
 .../cql3/selection/ResultSetBuilder.java        |  6 ++++
 .../cql3/validation/entities/TimestampTest.java | 30 ++++++++++++++++++++
 .../cql3/validation/operations/SelectTest.java  | 29 +++++++++++++++++++
 4 files changed, 66 insertions(+)
----------------------------------------------------------------------


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

http://git-wip-us.apache.org/repos/asf/cassandra/blob/de60cf07/src/java/org/apache/cassandra/cql3/selection/ResultSetBuilder.java
----------------------------------------------------------------------
diff --cc src/java/org/apache/cassandra/cql3/selection/ResultSetBuilder.java
index d179f93,0000000..9b7abe1
mode 100644,000000..100644
--- a/src/java/org/apache/cassandra/cql3/selection/ResultSetBuilder.java
+++ b/src/java/org/apache/cassandra/cql3/selection/ResultSetBuilder.java
@@@ -1,165 -1,0 +1,171 @@@
 +/*
 + * 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.selection;
 +
 +import java.nio.ByteBuffer;
 +import java.util.ArrayList;
 +import java.util.Arrays;
 +import java.util.List;
 +
 +import org.apache.cassandra.cql3.ResultSet;
 +import org.apache.cassandra.cql3.ResultSet.ResultMetadata;
 +import org.apache.cassandra.cql3.selection.Selection.Selectors;
 +import org.apache.cassandra.db.Clustering;
 +import org.apache.cassandra.db.DecoratedKey;
 +import org.apache.cassandra.db.aggregation.GroupMaker;
 +import org.apache.cassandra.db.context.CounterContext;
 +import org.apache.cassandra.db.rows.Cell;
 +import org.apache.cassandra.utils.ByteBufferUtil;
 +
 +public final class ResultSetBuilder
 +{
 +    private final ResultSet resultSet;
 +
 +    /**
 +     * As multiple thread can access a <code>Selection</code> instance each 
<code>ResultSetBuilder</code> will use
 +     * its own <code>Selectors</code> instance.
 +     */
 +    private final Selectors selectors;
 +
 +    /**
 +     * The <code>GroupMaker</code> used to build the aggregates.
 +     */
 +    private final GroupMaker groupMaker;
 +
 +    /*
 +     * We'll build CQL3 row one by one.
 +     * The currentRow is the values for the (CQL3) columns we've fetched.
 +     * We also collect timestamps and ttls for the case where the writetime 
and
 +     * ttl functions are used. Note that we might collect timestamp and/or 
ttls
 +     * we don't care about, but since the array below are allocated just once,
 +     * it doesn't matter performance wise.
 +     */
 +    List<ByteBuffer> current;
 +    final long[] timestamps;
 +    final int[] ttls;
 +
 +    public ResultSetBuilder(ResultMetadata metadata, Selectors selectors)
 +    {
 +        this(metadata, selectors, null);
 +    }
 +
 +    public ResultSetBuilder(ResultMetadata metadata, Selectors selectors, 
GroupMaker groupMaker)
 +    {
 +        this.resultSet = new ResultSet(metadata.copy(), new 
ArrayList<List<ByteBuffer>>());
 +        this.selectors = selectors;
 +        this.groupMaker = groupMaker;
 +        this.timestamps = selectors.collectTimestamps() ? new 
long[selectors.numberOfFetchedColumns()] : null;
 +        this.ttls = selectors.collectTTLs() ? new 
int[selectors.numberOfFetchedColumns()] : null;
 +
 +        // We use MIN_VALUE to indicate no timestamp and -1 for no ttl
 +        if (timestamps != null)
 +            Arrays.fill(timestamps, Long.MIN_VALUE);
 +        if (ttls != null)
 +            Arrays.fill(ttls, -1);
 +    }
 +
 +    public void add(ByteBuffer v)
 +    {
 +        current.add(v);
 +    }
 +
 +    public void add(Cell c, int nowInSec)
 +    {
 +        if (c == null)
 +        {
 +            current.add(null);
 +            return;
 +        }
 +
 +        current.add(value(c));
 +
 +        if (timestamps != null)
 +            timestamps[current.size() - 1] = c.timestamp();
 +
 +        if (ttls != null)
 +            ttls[current.size() - 1] = remainingTTL(c, nowInSec);
 +    }
 +
 +    private int remainingTTL(Cell c, int nowInSec)
 +    {
 +        if (!c.isExpiring())
 +            return -1;
 +
 +        int remaining = c.localDeletionTime() - nowInSec;
 +        return remaining >= 0 ? remaining : -1;
 +    }
 +
 +    private ByteBuffer value(Cell c)
 +    {
 +        return c.isCounterCell()
 +             ? 
ByteBufferUtil.bytes(CounterContext.instance().total(c.value()))
 +             : c.value();
 +    }
 +
 +    /**
 +     * Notifies this <code>Builder</code> that a new row is being processed.
 +     *
 +     * @param partitionKey the partition key of the new row
 +     * @param clustering the clustering of the new row
 +     */
 +    public void newRow(DecoratedKey partitionKey, Clustering clustering)
 +    {
 +        // The groupMaker needs to be called for each row
 +        boolean isNewAggregate = groupMaker == null || 
groupMaker.isNewGroup(partitionKey, clustering);
 +        if (current != null)
 +        {
 +            selectors.addInputRow(this);
 +            if (isNewAggregate)
 +            {
 +                resultSet.addRow(getOutputRow());
 +                selectors.reset();
 +            }
 +        }
 +        current = new ArrayList<>(selectors.numberOfFetchedColumns());
++
++        // Timestamps and TTLs are arrays per row, we must null them out 
between rows
++        if (timestamps != null)
++            Arrays.fill(timestamps, Long.MIN_VALUE);
++        if (ttls != null)
++            Arrays.fill(ttls, -1);
 +    }
 +
 +    /**
 +     * Builds the <code>ResultSet</code>
 +     */
 +    public ResultSet build()
 +    {
 +        if (current != null)
 +        {
 +            selectors.addInputRow(this);
 +            resultSet.addRow(getOutputRow());
 +            selectors.reset();
 +            current = null;
 +        }
 +
 +        // For aggregates we need to return a row even it no records have 
been found
 +        if (resultSet.isEmpty() && groupMaker != null && 
groupMaker.returnAtLeastOneRow())
 +            resultSet.addRow(getOutputRow());
 +        return resultSet;
 +    }
 +
 +    private List<ByteBuffer> getOutputRow()
 +    {
 +        return selectors.getOutputRow();
 +    }
 +}

http://git-wip-us.apache.org/repos/asf/cassandra/blob/de60cf07/test/unit/org/apache/cassandra/cql3/validation/entities/TimestampTest.java
----------------------------------------------------------------------
diff --cc 
test/unit/org/apache/cassandra/cql3/validation/entities/TimestampTest.java
index 3e70cd0,b41163c..985a5e0
--- a/test/unit/org/apache/cassandra/cql3/validation/entities/TimestampTest.java
+++ b/test/unit/org/apache/cassandra/cql3/validation/entities/TimestampTest.java
@@@ -152,4 -152,33 +152,34 @@@ public class TimestampTest extends CQLT
          execute("INSERT INTO %s (k, i) VALUES (1, 1) USING TIMESTAMP ?", 
unset()); // treat as 'now'
      }
  
+     @Test
+     public void testTimestampsOnUnsetColumns() throws Throwable
+     {
+         createTable("CREATE TABLE %s (k int PRIMARY KEY, i int)");
+         execute("INSERT INTO %s (k, i) VALUES (1, 1) USING TIMESTAMP 1;");
+         execute("INSERT INTO %s (k) VALUES (2) USING TIMESTAMP 2;");
+         execute("INSERT INTO %s (k, i) VALUES (3, 3) USING TIMESTAMP 1;");
+         assertRows(execute("SELECT k, i, writetime(i) FROM %s "),
+                    row(1, 1, 1L),
+                    row(2, null, null),
+                    row(3, 3, 1L));
+     }
+ 
+     @Test
+     public void testTimestampsOnUnsetColumnsWide() throws Throwable
+     {
+         createTable("CREATE TABLE %s (k int , c int, i int, PRIMARY KEY (k, 
c))");
+         execute("INSERT INTO %s (k, c, i) VALUES (1, 1, 1) USING TIMESTAMP 
1;");
+         execute("INSERT INTO %s (k, c) VALUES (1, 2) USING TIMESTAMP 1;");
+         execute("INSERT INTO %s (k, c, i) VALUES (1, 3, 1) USING TIMESTAMP 
1;");
+         execute("INSERT INTO %s (k, c) VALUES (2, 2) USING TIMESTAMP 2;");
+         execute("INSERT INTO %s (k, c, i) VALUES (3, 3, 3) USING TIMESTAMP 
1;");
+         assertRows(execute("SELECT k, c, i, writetime(i) FROM %s "),
+                    row(1, 1, 1, 1L),
+                    row(1, 2, null, null),
+                    row(1, 3, 1, 1L),
+                    row(2, 2, null, null),
+                    row(3, 3, 3, 1L));
+     }
++
  }

http://git-wip-us.apache.org/repos/asf/cassandra/blob/de60cf07/test/unit/org/apache/cassandra/cql3/validation/operations/SelectTest.java
----------------------------------------------------------------------
diff --cc 
test/unit/org/apache/cassandra/cql3/validation/operations/SelectTest.java
index c0a8a9c,7c6c589..54f11ff
--- a/test/unit/org/apache/cassandra/cql3/validation/operations/SelectTest.java
+++ b/test/unit/org/apache/cassandra/cql3/validation/operations/SelectTest.java
@@@ -4747,4 -4738,32 +4747,33 @@@ public class SelectTest extends CQLTest
              assertRows(execute("SELECT k, v FROM %s WHERE k = 0 AND m 
CONTAINS KEY 'c' ALLOW FILTERING"), row(0, 2));
          });
      }
+ 
+     @Test
+     public void testMixedTTLOnColumns() throws Throwable
+     {
+         createTable("CREATE TABLE %s (k int PRIMARY KEY, i int)");
+         execute("INSERT INTO %s (k) VALUES (2);");
+         execute("INSERT INTO %s (k, i) VALUES (1, 1) USING TTL 100;");
+         execute("INSERT INTO %s (k, i) VALUES (3, 3) USING TTL 100;");
+         assertRows(execute("SELECT k, i, TTL(i) FROM %s "),
+                    row(1, 1, 100), row(2, null, null), row(3, 3, 100));
+     }
+ 
+     @Test
+     public void testMixedTTLOnColumnsWide() throws Throwable
+     {
+         createTable("CREATE TABLE %s (k int, c int, i int, PRIMARY KEY (k, 
c))");
+         execute("INSERT INTO %s (k, c) VALUES (2, 2);");
+         execute("INSERT INTO %s (k, c, i) VALUES (1, 1, 1) USING TTL 100;");
+         execute("INSERT INTO %s (k, c) VALUES (1, 2) ;");
+         execute("INSERT INTO %s (k, c, i) VALUES (1, 3, 3) USING TTL 100;");
+         execute("INSERT INTO %s (k, c, i) VALUES (3, 3, 3) USING TTL 100;");
+         assertRows(execute("SELECT k, c, i, TTL(i) FROM %s "),
+                    row(1, 1, 1, 100),
+                    row(1, 2, null, null),
+                    row(1, 3, 3, 100),
+                    row(2, 2, null, null),
+                    row(3, 3, 3, 100));
+     }
++
  }


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

Reply via email to