cassandra-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From ifesdj...@apache.org
Subject [cassandra] 01/01: Merge branch 'cassandra-3.0' into cassandra-3.11
Date Wed, 22 Jan 2020 18:57:23 GMT
This is an automated email from the ASF dual-hosted git repository.

ifesdjeen pushed a commit to branch cassandra-3.11
in repository https://gitbox.apache.org/repos/asf/cassandra.git

commit 7cd0e92dcac8e3423f2eae08069bd5ebf6a3e236
Merge: 6a41aa5 b907dc9
Author: Alex Petrov <oleksandr.petrov@gmail.com>
AuthorDate: Wed Jan 22 19:53:09 2020 +0100

    Merge branch 'cassandra-3.0' into cassandra-3.11

 .../org/apache/cassandra/config/CFMetaData.java    | 26 +++++----
 .../apache/cassandra/config/ColumnDefinition.java  |  2 +-
 .../cql3/statements/CreateIndexStatement.java      |  2 +-
 .../cassandra/db/AbstractReadCommandBuilder.java   |  5 +-
 test/unit/org/apache/cassandra/cql3/ViewTest.java  | 63 ++++++++++++++--------
 .../cql3/validation/operations/AlterTest.java      |  3 ++
 .../cql3/validation/operations/InsertTest.java     | 12 ++---
 .../cql3/validation/operations/SelectTest.java     |  4 ++
 .../org/apache/cassandra/db/RowUpdateBuilder.java  | 16 +++---
 .../index/internal/CassandraIndexTest.java         |  9 ++++
 10 files changed, 90 insertions(+), 52 deletions(-)

diff --cc src/java/org/apache/cassandra/config/ColumnDefinition.java
index c819ae7,6f7f749..4de96a0
--- a/src/java/org/apache/cassandra/config/ColumnDefinition.java
+++ b/src/java/org/apache/cassandra/config/ColumnDefinition.java
@@@ -460,193 -410,4 +460,193 @@@ public class ColumnDefinition extends C
              return ((CollectionType) type).valueComparator().isCounter();
          return type.isCounter();
      }
 +
 +    public Selector.Factory newSelectorFactory(CFMetaData cfm, AbstractType<?> expectedType,
List<ColumnDefinition> defs, VariableSpecifications boundNames) throws InvalidRequestException
 +    {
 +        return SimpleSelector.newFactory(this, addAndGetIndex(this, defs));
 +    }
 +
 +    public AbstractType<?> getExactTypeIfKnown(String keyspace)
 +    {
 +        return type;
 +    }
 +
 +    /**
 +     * Because Thrift-created tables may have a non-text comparator, we cannot determine
the proper 'key' until
 +     * we know the comparator. ColumnDefinition.Raw is a placeholder that can be converted
to a real ColumnIdentifier
 +     * once the comparator is known with prepare(). This should only be used with identifiers
that are actual
 +     * column names. See CASSANDRA-8178 for more background.
 +     */
 +    public static abstract class Raw extends Selectable.Raw
 +    {
 +        /**
 +         * Creates a {@code ColumnDefinition.Raw} from an unquoted identifier string.
 +         */
 +        public static Raw forUnquoted(String text)
 +        {
 +            return new Literal(text, false);
 +        }
 +
 +        /**
 +         * Creates a {@code ColumnDefinition.Raw} from a quoted identifier string.
 +         */
 +        public static Raw forQuoted(String text)
 +        {
 +            return new Literal(text, true);
 +        }
 +
 +        /**
 +         * Creates a {@code ColumnDefinition.Raw} from a pre-existing {@code ColumnDefinition}
 +         * (useful in the rare cases where we already have the column but need
 +         * a {@code ColumnDefinition.Raw} for typing purposes).
 +         */
 +        public static Raw forColumn(ColumnDefinition column)
 +        {
 +            return new ForColumn(column);
 +        }
 +
 +        /**
 +         * Get the identifier corresponding to this raw column, without assuming this is
an
 +         * existing column (unlike {@link #prepare}).
 +         */
 +        public abstract ColumnIdentifier getIdentifier(CFMetaData cfm);
 +
 +        public abstract String rawText();
 +
 +        @Override
 +        public abstract ColumnDefinition prepare(CFMetaData cfm);
 +
 +        @Override
 +        public boolean processesSelection()
 +        {
 +            return false;
 +        }
 +
 +        @Override
 +        public final int hashCode()
 +        {
 +            return toString().hashCode();
 +        }
 +
 +        @Override
 +        public final boolean equals(Object o)
 +        {
 +            if(!(o instanceof Raw))
 +                return false;
 +
 +            Raw that = (Raw)o;
 +            return this.toString().equals(that.toString());
 +        }
 +
 +        private static class Literal extends Raw
 +        {
 +            private final String text;
 +
 +            public Literal(String rawText, boolean keepCase)
 +            {
 +                this.text =  keepCase ? rawText : rawText.toLowerCase(Locale.US);
 +            }
 +
 +            public ColumnIdentifier getIdentifier(CFMetaData cfm)
 +            {
 +                if (!cfm.isStaticCompactTable())
 +                    return ColumnIdentifier.getInterned(text, true);
 +
 +                AbstractType<?> thriftColumnNameType = cfm.thriftColumnNameType();
 +                if (thriftColumnNameType instanceof UTF8Type)
 +                    return ColumnIdentifier.getInterned(text, true);
 +
 +                // We have a Thrift-created table with a non-text comparator. Check if we
have a match column, otherwise assume we should use
 +                // thriftColumnNameType
 +                ByteBuffer bufferName = ByteBufferUtil.bytes(text);
 +                for (ColumnDefinition def : cfm.allColumns())
 +                {
 +                    if (def.name.bytes.equals(bufferName))
 +                        return def.name;
 +                }
 +                return ColumnIdentifier.getInterned(thriftColumnNameType, thriftColumnNameType.fromString(text),
text);
 +            }
 +
 +            public ColumnDefinition prepare(CFMetaData cfm)
 +            {
 +                if (!cfm.isStaticCompactTable())
 +                    return find(cfm);
 +
 +                AbstractType<?> thriftColumnNameType = cfm.thriftColumnNameType();
 +                if (thriftColumnNameType instanceof UTF8Type)
 +                    return find(cfm);
 +
 +                // We have a Thrift-created table with a non-text comparator. Check if we
have a match column, otherwise assume we should use
 +                // thriftColumnNameType
 +                ByteBuffer bufferName = ByteBufferUtil.bytes(text);
 +                for (ColumnDefinition def : cfm.allColumns())
 +                {
 +                    if (def.name.bytes.equals(bufferName))
 +                        return def;
 +                }
 +                return find(thriftColumnNameType.fromString(text), cfm);
 +            }
 +
 +            private ColumnDefinition find(CFMetaData cfm)
 +            {
 +                return find(ByteBufferUtil.bytes(text), cfm);
 +            }
 +
 +            private ColumnDefinition find(ByteBuffer id, CFMetaData cfm)
 +            {
-                 ColumnDefinition def = cfm.getColumnDefinition(id);
++                ColumnDefinition def = cfm.getColumnDefinitionForCQL(id);
 +                if (def == null)
 +                    throw new InvalidRequestException(String.format("Undefined column name
%s", toString()));
 +                return def;
 +            }
 +
 +            public String rawText()
 +            {
 +                return text;
 +            }
 +
 +            @Override
 +            public String toString()
 +            {
 +                return ColumnIdentifier.maybeQuote(text);
 +            }
 +        }
 +
 +        // Use internally in the rare case where we need a ColumnDefinition.Raw for type-checking
but
 +        // actually already have the column itself.
 +        private static class ForColumn extends Raw
 +        {
 +            private final ColumnDefinition column;
 +
 +            private ForColumn(ColumnDefinition column)
 +            {
 +                this.column = column;
 +            }
 +
 +            public ColumnIdentifier getIdentifier(CFMetaData cfm)
 +            {
 +                return column.name;
 +            }
 +
 +            public ColumnDefinition prepare(CFMetaData cfm)
 +            {
 +                assert cfm.getColumnDefinition(column.name) != null; // Sanity check that
we're not doing something crazy
 +                return column;
 +            }
 +
 +            public String rawText()
 +            {
 +                return column.name.toString();
 +            }
 +
 +            @Override
 +            public String toString()
 +            {
 +                return column.name.toCQLString();
 +            }
 +        }
 +    }
 +
 +
 +
  }
diff --cc src/java/org/apache/cassandra/db/AbstractReadCommandBuilder.java
index 1c69813,a7f3319..ba91db8
--- a/src/java/org/apache/cassandra/db/AbstractReadCommandBuilder.java
+++ b/src/java/org/apache/cassandra/db/AbstractReadCommandBuilder.java
@@@ -161,9 -163,10 +163,10 @@@ public abstract class AbstractReadComma
          throw new AssertionError();
      }
  
+     @VisibleForTesting
      public AbstractReadCommandBuilder filterOn(String column, Operator op, Object value)
      {
--        ColumnDefinition def = cfs.metadata.getColumnDefinition(ColumnIdentifier.getInterned(column,
true));
++        ColumnDefinition def = cfs.metadata.getColumnDefinitionForCQL(ColumnIdentifier.getInterned(column,
true));
          assert def != null;
  
          AbstractType<?> type = def.type;
diff --cc test/unit/org/apache/cassandra/cql3/ViewTest.java
index 8a98a8e,0d49e4b..9978f1d
--- a/test/unit/org/apache/cassandra/cql3/ViewTest.java
+++ b/test/unit/org/apache/cassandra/cql3/ViewTest.java
@@@ -46,13 -48,11 +46,14 @@@ import org.apache.cassandra.db.Keyspace
  import org.apache.cassandra.db.SystemKeyspace;
  import org.apache.cassandra.db.compaction.CompactionManager;
  import org.apache.cassandra.db.marshal.AsciiType;
 -import org.apache.cassandra.exceptions.InvalidRequestException;
 +import org.apache.cassandra.db.view.View;
  import org.apache.cassandra.exceptions.SyntaxException;
  import org.apache.cassandra.schema.KeyspaceParams;
 +import org.apache.cassandra.service.ClientWarn;
 +import org.apache.cassandra.transport.ProtocolVersion;
  import org.apache.cassandra.utils.FBUtilities;
  
++import static junit.framework.Assert.fail;
  import static org.junit.Assert.assertEquals;
  import static org.junit.Assert.assertTrue;
  
@@@ -228,7 -215,7 +229,7 @@@ public class ViewTest extends CQLTeste
          try
          {
              createView("mv_test", "CREATE MATERIALIZED VIEW %s AS SELECT * FROM %%s");
--            Assert.fail("Should fail if no primary key is filtered as NOT NULL");
++            fail("Should fail if no primary key is filtered as NOT NULL");
          }
          catch (Exception e)
          {
@@@ -238,7 -225,7 +239,7 @@@
          try
          {
              createView("mv_test", "CREATE MATERIALIZED VIEW %s AS SELECT * FROM %%s WHERE
bigintval IS NOT NULL AND asciival IS NOT NULL PRIMARY KEY (bigintval, k, asciival)");
--            Assert.fail("Should fail if compound primary is not completely filtered as NOT
NULL");
++            fail("Should fail if compound primary is not completely filtered as NOT NULL");
          }
          catch (Exception e)
          {
@@@ -254,7 -241,7 +255,7 @@@
          try
          {
              createView("mv_test", "CREATE MATERIALIZED VIEW %s AS SELECT * FROM %%s");
--            Assert.fail("Should fail if no primary key is filtered as NOT NULL");
++            fail("Should fail if no primary key is filtered as NOT NULL");
          }
          catch (Exception e)
          {
@@@ -280,7 -267,7 +281,7 @@@
          try
          {
              createView("mv_static", "CREATE MATERIALIZED VIEW %%s AS SELECT * FROM %s WHERE
sval IS NOT NULL AND k IS NOT NULL AND c IS NOT NULL PRIMARY KEY (sval,k,c)");
--            Assert.fail("Use of static column in a MV primary key should fail");
++            fail("Use of static column in a MV primary key should fail");
          }
          catch (InvalidQueryException e)
          {
@@@ -289,7 -276,7 +290,7 @@@
          try
          {
              createView("mv_static", "CREATE MATERIALIZED VIEW %%s AS SELECT val, sval FROM
%s WHERE val IS NOT NULL AND  k IS NOT NULL AND c IS NOT NULL PRIMARY KEY (val, k, c)");
--            Assert.fail("Explicit select of static column in MV should fail");
++            fail("Explicit select of static column in MV should fail");
          }
          catch (InvalidQueryException e)
          {
@@@ -298,7 -285,7 +299,7 @@@
          try
          {
              createView("mv_static", "CREATE MATERIALIZED VIEW %s AS SELECT * FROM %%s WHERE
val IS NOT NULL AND k IS NOT NULL AND c IS NOT NULL PRIMARY KEY (val,k,c)");
--            Assert.fail("Implicit select of static column in MV should fail");
++            fail("Implicit select of static column in MV should fail");
          }
          catch (InvalidQueryException e)
          {
@@@ -402,7 -389,7 +403,7 @@@
          try
          {
              createView("mv_counter", "CREATE MATERIALIZED VIEW %s AS SELECT * FROM %%s WHERE
count IS NOT NULL AND k IS NOT NULL PRIMARY KEY (count,k)");
--            Assert.fail("MV on counter should fail");
++            fail("MV on counter should fail");
          }
          catch (InvalidQueryException e)
          {
@@@ -424,7 -411,7 +425,7 @@@
          try
          {
              createView("mv_super_column", "CREATE MATERIALIZED VIEW %s AS SELECT * FROM
" + keyspace + "." + table + " WHERE key IS NOT NULL AND column1 IS NOT NULL PRIMARY KEY (key,column1)");
--            Assert.fail("MV on SuperColumn table should fail");
++            fail("MV on SuperColumn table should fail");
          }
          catch (InvalidQueryException e)
          {
@@@ -442,14 -430,38 +443,14 @@@
          execute("USE " + keyspace());
          executeNet(protocolVersion, "USE " + keyspace());
  
 -        // Must NOT include "default_time_to_live" for Materialized View creation
          try
          {
 -            createView("mv_ttl1", "CREATE MATERIALIZED VIEW %s AS SELECT * FROM %%s WHERE
k IS NOT NULL AND c IS NOT NULL PRIMARY KEY (k,c) WITH default_time_to_live = 30");
 -            Assert.fail("Should fail if TTL is provided for materialized view");
 -        }
 -        catch (Exception e)
 -        {
 +            createView("mv_duration", "CREATE MATERIALIZED VIEW %s AS SELECT * FROM %%s
WHERE result IS NOT NULL AND k IS NOT NULL PRIMARY KEY (result,k)");
-             Assert.fail("MV on duration should fail");
++            fail("MV on duration should fail");
          }
 -    }
 -
 -    @Test
 -    public void testAlterMvWithTTL() throws Throwable
 -    {
 -        createTable("CREATE TABLE %s (" +
 -                    "k int PRIMARY KEY, " +
 -                    "c int, " +
 -                    "val int) WITH default_time_to_live = 60");
 -
 -        execute("USE " + keyspace());
 -        executeNet(protocolVersion, "USE " + keyspace());
 -
 -        createView("mv_ttl2", "CREATE MATERIALIZED VIEW %s AS SELECT * FROM %%s WHERE k
IS NOT NULL AND c IS NOT NULL PRIMARY KEY (k,c)");
 -
 -        // Must NOT include "default_time_to_live" on alter Materialized View
 -        try
 -        {
 -            executeNet(protocolVersion, "ALTER MATERIALIZED VIEW %s WITH default_time_to_live
= 30");
 -            Assert.fail("Should fail if TTL is provided while altering materialized view");
 -        }
 -        catch (Exception e)
 +        catch (InvalidQueryException e)
          {
 +            Assert.assertEquals("Cannot use Duration column 'result' in PRIMARY KEY of materialized
view", e.getMessage());
          }
      }
  
@@@ -737,12 -749,12 +738,12 @@@
                  createView("mv1_" + def.name, query);
  
                  if (def.type.isMultiCell())
--                    Assert.fail("MV on a multicell should fail " + def);
++                    fail("MV on a multicell should fail " + def);
              }
              catch (InvalidQueryException e)
              {
                  if (!def.type.isMultiCell() && !def.isPartitionKey())
--                    Assert.fail("MV creation failed on " + def);
++                    fail("MV creation failed on " + def);
              }
  
  
@@@ -754,12 -766,12 +755,12 @@@
                  createView("mv2_" + def.name, query);
  
                  if (def.type.isMultiCell())
--                    Assert.fail("MV on a multicell should fail " + def);
++                    fail("MV on a multicell should fail " + def);
              }
              catch (InvalidQueryException e)
              {
                  if (!def.type.isMultiCell() && !def.isPartitionKey())
--                    Assert.fail("MV creation failed on " + def);
++                    fail("MV creation failed on " + def);
              }
  
              try
@@@ -769,12 -781,12 +770,12 @@@
                  createView("mv3_" + def.name, query);
  
                  if (def.type.isMultiCell())
--                    Assert.fail("MV on a multicell should fail " + def);
++                    fail("MV on a multicell should fail " + def);
              }
              catch (InvalidQueryException e)
              {
                  if (!def.type.isMultiCell() && !def.isPartitionKey())
--                    Assert.fail("MV creation failed on " + def);
++                    fail("MV creation failed on " + def);
              }
  
  
@@@ -784,7 -796,7 +785,7 @@@
                                 + (def.name.toString().equals("asciival") ? "" : "AND asciival
IS NOT NULL ") + "PRIMARY KEY ((" + def.name + ", k), asciival)";
                  createView("mv3_" + def.name, query);
  
--                Assert.fail("Should fail on duplicate name");
++                fail("Should fail on duplicate name");
              }
              catch (Exception e)
              {
@@@ -795,7 -807,7 +796,7 @@@
                  String query = "CREATE MATERIALIZED VIEW %s AS SELECT * FROM %%s WHERE "
+ def.name + " IS NOT NULL AND k IS NOT NULL "
                                 + (def.name.toString().equals("asciival") ? "" : "AND asciival
IS NOT NULL ") + "PRIMARY KEY ((" + def.name + ", k), nonexistentcolumn)";
                  createView("mv3_" + def.name, query);
--                Assert.fail("Should fail with unknown base column");
++                fail("Should fail with unknown base column");
              }
              catch (InvalidQueryException e)
              {
@@@ -1246,7 -1225,7 +1247,7 @@@
          try
          {
              createView("mv_de", "CREATE MATERIALIZED VIEW %s AS SELECT * FROM %%s WHERE
a IS NOT NULL AND b IS NOT NULL AND c IS NOT NULL AND d IS NOT NULL AND e IS NOT NULL PRIMARY
KEY ((d, a), b, e, c)");
--            Assert.fail("Should have rejected a query including multiple non-primary key
base columns");
++            fail("Should have rejected a query including multiple non-primary key base columns");
          }
          catch (Exception e)
          {
@@@ -1255,7 -1234,7 +1256,7 @@@
          try
          {
              createView("mv_de", "CREATE MATERIALIZED VIEW %s AS SELECT * FROM %%s WHERE
a IS NOT NULL AND b IS NOT NULL AND c IS NOT NULL AND d IS NOT NULL AND e IS NOT NULL PRIMARY
KEY ((a, b), c, d, e)");
--            Assert.fail("Should have rejected a query including multiple non-primary key
base columns");
++            fail("Should have rejected a query including multiple non-primary key base columns");
          }
          catch (Exception e)
          {
@@@ -1311,48 -1290,6 +1312,48 @@@
          assertRowsNet(protocolVersion, executeNet(protocolVersion, "SELECT * FROM mv"),
row(1, 0));
      }
  
 +    public void testCreateMvWithTTL() throws Throwable
 +    {
 +        createTable("CREATE TABLE %s (" +
 +                "k int PRIMARY KEY, " +
 +                "c int, " +
 +                "val int) WITH default_time_to_live = 60");
 +
 +        execute("USE " + keyspace());
 +        executeNet(protocolVersion, "USE " + keyspace());
 +
 +        // Must NOT include "default_time_to_live" for Materialized View creation
 +        try
 +        {
 +            createView("mv_ttl1", "CREATE MATERIALIZED VIEW %s AS SELECT * FROM %%s WHERE
k IS NOT NULL AND c IS NOT NULL PRIMARY KEY (k,c) WITH default_time_to_live = 30");
-             Assert.fail("Should fail if TTL is provided for materialized view");
++            fail("Should fail if TTL is provided for materialized view");
 +        }
 +        catch (Exception e)
 +        {
 +        }
 +    }
 +
 +    @Test
 +    public void testAlterMvWithTTL() throws Throwable
 +    {
 +        createTable("CREATE TABLE %s (" +
 +                    "k int PRIMARY KEY, " +
 +                    "c int, " +
 +                    "val int) WITH default_time_to_live = 60");
 +
 +        createView("mv_ttl2", "CREATE MATERIALIZED VIEW %s AS SELECT * FROM %%s WHERE k
IS NOT NULL AND c IS NOT NULL PRIMARY KEY (k,c)");
 +
 +        // Must NOT include "default_time_to_live" on alter Materialized View
 +        try
 +        {
 +            executeNet(protocolVersion, "ALTER MATERIALIZED VIEW %s WITH default_time_to_live
= 30");
-             Assert.fail("Should fail if TTL is provided while altering materialized view");
++            fail("Should fail if TTL is provided while altering materialized view");
 +        }
 +        catch (Exception e)
 +        {
 +        }
 +    }
 +
      @Test
      public void testViewBuilderResume() throws Throwable
      {
@@@ -1421,51 -1390,22 +1422,69 @@@
           execute("CREATE MATERIALIZED VIEW myview AS SELECT a, b FROM \"\" WHERE b IS NOT
NULL PRIMARY KEY (b, a)");
       }
  
 +    /**
 +     * Tests that a client warning is issued on materialized view creation.
 +     */
 +    @Test
 +    public void testClientWarningOnCreate() throws Throwable
 +    {
 +        createTable("CREATE TABLE %s (k int PRIMARY KEY, v int)");
 +
 +        ClientWarn.instance.captureWarnings();
 +        String viewName = keyspace() + ".warning_view";
 +        execute("CREATE MATERIALIZED VIEW " + viewName +
 +                " AS SELECT v FROM %s WHERE k IS NOT NULL AND v IS NOT NULL PRIMARY KEY
(v, k)");
 +        views.add(viewName);
 +        List<String> warnings = ClientWarn.instance.getWarnings();
 +
 +        Assert.assertNotNull(warnings);
 +        Assert.assertEquals(1, warnings.size());
 +        Assert.assertEquals(View.USAGE_WARNING, warnings.get(0));
 +    }
 +
 +    /**
 +     * Tests the configuration flag to disable materialized views.
 +     */
 +    @Test
 +    public void testDisableMaterializedViews() throws Throwable
 +    {
 +        createTable("CREATE TABLE %s (k int PRIMARY KEY, v int)");
 +
 +        executeNet(protocolVersion, "USE " + keyspace());
 +
 +        boolean enableMaterializedViews = DatabaseDescriptor.getEnableMaterializedViews();
 +        try
 +        {
 +            DatabaseDescriptor.setEnableMaterializedViews(false);
 +            createView("view1", "CREATE MATERIALIZED VIEW %s AS SELECT v FROM %%s WHERE
k IS NOT NULL AND v IS NOT NULL PRIMARY KEY (v, k)");
-             Assert.fail("Should not be able to create a materialized view if they are disabled");
++            fail("Should not be able to create a materialized view if they are disabled");
 +        }
 +        catch (Throwable e)
 +        {
 +            Assert.assertTrue(e instanceof InvalidQueryException);
 +            Assert.assertTrue(e.getMessage().contains("Materialized views are disabled"));
 +        }
 +        finally
 +        {
 +            DatabaseDescriptor.setEnableMaterializedViews(enableMaterializedViews);
 +        }
 +    }
++
+     @Test
+     public void viewOnCompactTableTest() throws Throwable
+     {
+         createTable("CREATE TABLE %s (a int, b int, v int, PRIMARY KEY (a, b)) WITH COMPACT
STORAGE");
+         executeNet(protocolVersion, "USE " + keyspace());
+         try
+         {
+             createView("mv",
+                        "CREATE MATERIALIZED VIEW %s AS SELECT a, b, value FROM %%s WHERE
b IS NOT NULL PRIMARY KEY (b, a)");
+             fail("Should have thrown an exception");
+         }
+         catch (Throwable t)
+         {
 -            Assert.assertEquals("Unknown column name detected in CREATE MATERIALIZED VIEW
statement : value",
++            Assert.assertEquals("Undefined column name value",
+                                 t.getMessage());
+         }
+     }
 -
  }
diff --cc test/unit/org/apache/cassandra/cql3/validation/operations/InsertTest.java
index 5f1c435,e467291..06cc1a3
--- a/test/unit/org/apache/cassandra/cql3/validation/operations/InsertTest.java
+++ b/test/unit/org/apache/cassandra/cql3/validation/operations/InsertTest.java
@@@ -247,26 -232,26 +247,26 @@@ public class InsertTest extends CQLTest
          createTable(tableQuery);
  
          // pass correct types to the hidden columns
 -        assertInvalidMessage("Unknown identifier column1",
 +        assertInvalidMessage("Undefined column name column1",
                               "INSERT INTO %s (a, b, column1) VALUES (?, ?, ?)",
-                              1, 1, 1, ByteBufferUtil.bytes('a'));
+                              1, 1, ByteBufferUtil.bytes('a'));
 -        assertInvalidMessage("Unknown identifier value",
 +        assertInvalidMessage("Undefined column name value",
                               "INSERT INTO %s (a, b, value) VALUES (?, ?, ?)",
-                              1, 1, 1, ByteBufferUtil.bytes('a'));
+                              1, 1, ByteBufferUtil.bytes('a'));
 -        assertInvalidMessage("Unknown identifier column1",
 +        assertInvalidMessage("Undefined column name column1",
                               "INSERT INTO %s (a, b, column1, value) VALUES (?, ?, ?, ?)",
-                              1, 1, 1, ByteBufferUtil.bytes('a'), ByteBufferUtil.bytes('b'));
+                              1, 1, ByteBufferUtil.bytes('a'), ByteBufferUtil.bytes('b'));
 -        assertInvalidMessage("Unknown identifier value",
 +        assertInvalidMessage("Undefined column name value",
                               "INSERT INTO %s (a, b, value, column1) VALUES (?, ?, ?, ?)",
-                              1, 1, 1, ByteBufferUtil.bytes('a'), ByteBufferUtil.bytes('b'));
+                              1, 1, ByteBufferUtil.bytes('a'), ByteBufferUtil.bytes('b'));
  
          // pass incorrect types to the hidden columns
 -        assertInvalidMessage("Unknown identifier value",
 +        assertInvalidMessage("Undefined column name value",
                               "INSERT INTO %s (a, b, value) VALUES (?, ?, ?)",
-                              1, 1, 1, 1);
+                              1, 1, 1);
 -        assertInvalidMessage("Unknown identifier column1",
 +        assertInvalidMessage("Undefined column name column1",
                               "INSERT INTO %s (a, b, column1) VALUES (?, ?, ?)",
-                              1, 1, 1, 1);
+                              1, 1, 1);
          assertEmpty(execute("SELECT * FROM %s"));
  
          // pass null to the hidden columns
diff --cc test/unit/org/apache/cassandra/cql3/validation/operations/SelectTest.java
index dcf454a,f88dd2f..ee9cd7f
--- a/test/unit/org/apache/cassandra/cql3/validation/operations/SelectTest.java
+++ b/test/unit/org/apache/cassandra/cql3/validation/operations/SelectTest.java
@@@ -4856,19 -3083,23 +4856,23 @@@ public class SelectTest extends CQLTest
  
      private void testWithCompactFormat() throws Throwable
      {
 -        assertInvalidMessage("Order by on unknown column value",
++        assertInvalidMessage("Undefined column name value",
+                              "SELECT * FROM %s WHERE a IN (1,2,3) ORDER BY value ASC");
 -        assertInvalidMessage("Order by on unknown column column1",
++        assertInvalidMessage("Undefined column name column1",
+                              "SELECT * FROM %s WHERE a IN (1,2,3) ORDER BY column1 ASC");
 -        assertInvalidMessage("Undefined name column1 in selection clause",
 +        assertInvalidMessage("Undefined column name column1",
                               "SELECT column1 FROM %s");
 -        assertInvalidMessage("Undefined name value in selection clause",
 +        assertInvalidMessage("Undefined column name value",
                               "SELECT value FROM %s");
 -        assertInvalidMessage("Undefined name value in selection clause",
 +        assertInvalidMessage("Undefined column name value",
                               "SELECT value, column1 FROM %s");
 -        assertInvalid("Undefined name column1 in where clause ('column1 = NULL')",
 +        assertInvalid("Undefined column name column1",
                        "SELECT * FROM %s WHERE column1 = null ALLOW FILTERING");
 -        assertInvalid("Undefined name value in where clause ('value = NULL')",
 +        assertInvalid("Undefined column name value",
                        "SELECT * FROM %s WHERE value = null ALLOW FILTERING");
 -        assertInvalidMessage("Undefined name column1 in selection clause",
 +        assertInvalidMessage("Undefined column name column1",
                               "SELECT WRITETIME(column1) FROM %s");
 -        assertInvalidMessage("Undefined name value in selection clause",
 +        assertInvalidMessage("Undefined column name value",
                               "SELECT WRITETIME(value) FROM %s");
      }
  }
diff --cc test/unit/org/apache/cassandra/db/RowUpdateBuilder.java
index 8e71d64,0000000..8535616
mode 100644,000000..100644
--- a/test/unit/org/apache/cassandra/db/RowUpdateBuilder.java
+++ b/test/unit/org/apache/cassandra/db/RowUpdateBuilder.java
@@@ -1,196 -1,0 +1,192 @@@
 +/*
 + * 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.db;
 +
 +import java.nio.ByteBuffer;
- import java.util.*;
++import java.util.ArrayList;
++import java.util.List;
 +
- import org.apache.cassandra.cql3.ColumnIdentifier;
 +import org.apache.cassandra.config.CFMetaData;
 +import org.apache.cassandra.config.ColumnDefinition;
- import org.apache.cassandra.db.marshal.SetType;
- import org.apache.cassandra.db.rows.*;
- import org.apache.cassandra.db.context.CounterContext;
- import org.apache.cassandra.db.partitions.*;
- import org.apache.cassandra.db.marshal.AbstractType;
- import org.apache.cassandra.db.marshal.ListType;
- import org.apache.cassandra.db.marshal.MapType;
- import org.apache.cassandra.utils.*;
++import org.apache.cassandra.db.partitions.PartitionUpdate;
++import org.apache.cassandra.db.rows.BTreeRow;
++import org.apache.cassandra.db.rows.Row;
++import org.apache.cassandra.utils.FBUtilities;
 +
 +/**
 + * Convenience object to create single row updates for tests.
 + *
 + * This is a thin wrapper over the builders in SimpleBuilders for historical reasons.
 + * We could modify all the tests using this class to use the simple builders directly
 + * instead, but there is a fair amount of use so the value of such effort is unclear.
 + */
 +public class RowUpdateBuilder
 +{
 +    private final PartitionUpdate.SimpleBuilder updateBuilder;
 +    private Row.SimpleBuilder rowBuilder;
 +    private boolean noRowMarker;
 +
 +    private List<RangeTombstone> rts = new ArrayList<>();
 +
 +    private RowUpdateBuilder(PartitionUpdate.SimpleBuilder updateBuilder)
 +    {
 +        this.updateBuilder = updateBuilder;
 +    }
 +
 +    public RowUpdateBuilder(CFMetaData metadata, long timestamp, Object partitionKey)
 +    {
 +        this(metadata, FBUtilities.nowInSeconds(), timestamp, partitionKey);
 +    }
 +
 +    public RowUpdateBuilder(CFMetaData metadata, int localDeletionTime, long timestamp,
Object partitionKey)
 +    {
 +        this(metadata, localDeletionTime, timestamp, metadata.params.defaultTimeToLive,
partitionKey);
 +    }
 +
 +    public RowUpdateBuilder(CFMetaData metadata, long timestamp, int ttl, Object partitionKey)
 +    {
 +        this(metadata, FBUtilities.nowInSeconds(), timestamp, ttl, partitionKey);
 +    }
 +
 +    public RowUpdateBuilder(CFMetaData metadata, int localDeletionTime, long timestamp,
int ttl, Object partitionKey)
 +    {
 +        this(PartitionUpdate.simpleBuilder(metadata, partitionKey));
 +
 +        this.updateBuilder.timestamp(timestamp);
 +        this.updateBuilder.ttl(ttl);
 +        this.updateBuilder.nowInSec(localDeletionTime);
 +    }
 +
 +    private Row.SimpleBuilder rowBuilder()
 +    {
 +        // Normally, rowBuilder is created by the call to clustering(), but we allow skipping
that call for an empty
 +        // clustering.
 +        if (rowBuilder == null)
 +        {
 +            rowBuilder = updateBuilder.row();
 +            if (noRowMarker)
 +                rowBuilder.noPrimaryKeyLivenessInfo();
 +        }
 +
 +        return rowBuilder;
 +    }
 +
 +    // This must be called before any addition or deletion if used.
 +    public RowUpdateBuilder noRowMarker()
 +    {
 +        this.noRowMarker = true;
 +        if (rowBuilder != null)
 +            rowBuilder.noPrimaryKeyLivenessInfo();
 +        return this;
 +    }
 +
 +    public RowUpdateBuilder clustering(Object... clusteringValues)
 +    {
 +        assert rowBuilder == null;
 +        rowBuilder = updateBuilder.row(clusteringValues);
 +        if (noRowMarker)
 +            rowBuilder.noPrimaryKeyLivenessInfo();
 +        return this;
 +    }
 +
 +    public Mutation build()
 +    {
 +        return new Mutation(buildUpdate());
 +    }
 +
 +    public PartitionUpdate buildUpdate()
 +    {
 +        PartitionUpdate update = updateBuilder.build();
 +        for (RangeTombstone rt : rts)
 +            update.add(rt);
 +        return update;
 +    }
 +
 +    private static void deleteRow(PartitionUpdate update, long timestamp, int localDeletionTime,
Object... clusteringValues)
 +    {
 +        assert clusteringValues.length == update.metadata().comparator.size() || (clusteringValues.length
== 0 && !update.columns().statics.isEmpty());
 +
 +        boolean isStatic = clusteringValues.length != update.metadata().comparator.size();
 +        Row.Builder builder = BTreeRow.sortedBuilder();
 +
 +        if (isStatic)
 +            builder.newRow(Clustering.STATIC_CLUSTERING);
 +        else
 +            builder.newRow(clusteringValues.length == 0 ? Clustering.EMPTY : update.metadata().comparator.make(clusteringValues));
 +        builder.addRowDeletion(Row.Deletion.regular(new DeletionTime(timestamp, localDeletionTime)));
 +
 +        update.add(builder.build());
 +    }
 +
 +    public static Mutation deleteRow(CFMetaData metadata, long timestamp, Object key, Object...
clusteringValues)
 +    {
 +        return deleteRowAt(metadata, timestamp, FBUtilities.nowInSeconds(), key, clusteringValues);
 +    }
 +
 +    public static Mutation deleteRowAt(CFMetaData metadata, long timestamp, int localDeletionTime,
Object key, Object... clusteringValues)
 +    {
 +        PartitionUpdate update = new PartitionUpdate(metadata, makeKey(metadata, key), metadata.partitionColumns(),
0);
 +        deleteRow(update, timestamp, localDeletionTime, clusteringValues);
 +        // note that the created mutation may get further update later on, so we don't use
the ctor that create a singletonMap
 +        // underneath (this class if for convenience, not performance)
 +        return new Mutation(update.metadata().ksName, update.partitionKey()).add(update);
 +    }
 +
 +    private static DecoratedKey makeKey(CFMetaData metadata, Object... partitionKey)
 +    {
 +        if (partitionKey.length == 1 && partitionKey[0] instanceof DecoratedKey)
 +            return (DecoratedKey)partitionKey[0];
 +
 +        ByteBuffer key = CFMetaData.serializePartitionKey(metadata.getKeyValidatorAsClusteringComparator().make(partitionKey));
 +        return metadata.decorateKey(key);
 +    }
 +
 +    public RowUpdateBuilder addRangeTombstone(RangeTombstone rt)
 +    {
 +        rts.add(rt);
 +        return this;
 +    }
 +
 +    public RowUpdateBuilder addRangeTombstone(Object start, Object end)
 +    {
 +        updateBuilder.addRangeTombstone().start(start).end(end);
 +        return this;
 +    }
 +
 +    public RowUpdateBuilder add(String columnName, Object value)
 +    {
 +        rowBuilder().add(columnName, value);
 +        return this;
 +    }
 +
 +    public RowUpdateBuilder add(ColumnDefinition columnDefinition, Object value)
 +    {
 +        return add(columnDefinition.name.toString(), value);
 +    }
 +
 +    public RowUpdateBuilder delete(String columnName)
 +    {
 +        rowBuilder().delete(columnName);
 +        return this;
 +    }
 +
 +    public RowUpdateBuilder delete(ColumnDefinition columnDefinition)
 +    {
 +        return delete(columnDefinition.name.toString());
 +    }
 +}
diff --cc test/unit/org/apache/cassandra/index/internal/CassandraIndexTest.java
index 1f8fe71,286c418..23b27b8
--- a/test/unit/org/apache/cassandra/index/internal/CassandraIndexTest.java
+++ b/test/unit/org/apache/cassandra/index/internal/CassandraIndexTest.java
@@@ -340,32 -340,14 +341,40 @@@ public class CassandraIndexTest extend
      }
  
      @Test
 +    public void indexOnStaticColumn() throws Throwable
 +    {
 +        Object[] row1 = row("k0", "c0", "s0");
 +        Object[] row2 = row("k0", "c1", "s0");
 +        Object[] row3 = row("k1", "c0", "s1");
 +        Object[] row4 = row("k1", "c1", "s1");
 +
 +        createTable("CREATE TABLE %s (k text, c text, s text static, PRIMARY KEY (k, c));");
 +        createIndex("CREATE INDEX sc_index on %s(s)");
 +
 +        execute("INSERT INTO %s (k, c, s) VALUES (?, ?, ?)", row1);
 +        execute("INSERT INTO %s (k, c, s) VALUES (?, ?, ?)", row2);
 +        execute("INSERT INTO %s (k, c, s) VALUES (?, ?, ?)", row3);
 +        execute("INSERT INTO %s (k, c, s) VALUES (?, ?, ?)", row4);
 +
 +        assertRows(execute("SELECT * FROM %s WHERE s = ?", "s0"), row1, row2);
 +        assertRows(execute("SELECT * FROM %s WHERE s = ?", "s1"), row3, row4);
 +
 +        assertRows(execute("SELECT * FROM %s WHERE s = ? AND token(k) >= token(?)", "s0",
"k0"), row1, row2);
 +        assertRows(execute("SELECT * FROM %s WHERE s = ? AND token(k) >= token(?)", "s1",
"k1"), row3, row4);
 +
 +        assertEmpty(execute("SELECT * FROM %s WHERE s = ? AND token(k) < token(?)", "s0",
"k0"));
 +        assertEmpty(execute("SELECT * FROM %s WHERE s = ? AND token(k) < token(?)", "s1",
"k1"));
 +    }
 +
 +    @Test
+     public void testIndexOnCompactTable() throws Throwable
+     {
+         createTable("CREATE TABLE %s (k int, v int, PRIMARY KEY (k)) WITH COMPACT STORAGE;");
 -        assertInvalidMessage("No column definition found for column value",
++        assertInvalidMessage("Undefined column name value",
+                              "CREATE INDEX idx_value ON %s(value)");
+     }
+ 
+     @Test
      public void indexOnClusteringColumnWithoutRegularColumns() throws Throwable
      {
          Object[] row1 = row("k0", "c0");


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


Mime
View raw message