This is an automated email from the ASF dual-hosted git repository.

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


The following commit(s) were added to refs/heads/cassandra-3.11 by this push:
     new e6a61be  Add flag to disable SASI indexes, and warning on creation
e6a61be is described below

commit e6a61be8c857106d5d99a270b2d17de9f84c4d67
Author: Andrés de la Peña <a.penya.gar...@gmail.com>
AuthorDate: Tue Nov 6 19:01:47 2018 +0000

    Add flag to disable SASI indexes, and warning on creation
    
    patch by Andres de la Peña; reviewed by Robert Stupp for CASSANDRA-14866
---
 CHANGES.txt                                        |  5 +-
 NEWS.txt                                           |  8 ++++
 conf/cassandra.yaml                                | 19 ++++++--
 src/java/org/apache/cassandra/config/Config.java   |  2 +
 .../cassandra/config/DatabaseDescriptor.java       | 17 ++++++-
 .../cql3/statements/CreateIndexStatement.java      | 15 +++++-
 .../cql3/statements/CreateViewStatement.java       |  9 ++--
 src/java/org/apache/cassandra/db/view/View.java    |  3 +-
 .../org/apache/cassandra/index/sasi/SASIIndex.java |  2 +
 test/unit/org/apache/cassandra/cql3/ViewTest.java  | 55 ++++++++++++++++++++--
 .../apache/cassandra/index/sasi/SASICQLTest.java   | 48 +++++++++++++++++++
 11 files changed, 164 insertions(+), 19 deletions(-)

diff --git a/CHANGES.txt b/CHANGES.txt
index 2f9813e..f520aed 100644
--- a/CHANGES.txt
+++ b/CHANGES.txt
@@ -1,10 +1,11 @@
 3.11.5
+ * Add flag to disable SASI indexes, and warnings on creation (CASSANDRA-14866)
 Merged from 3.0:
  * Improve `nodetool status -r` speed (CASSANDRA-14847)
  * Improve merkle tree size and time on heap (CASSANDRA-14096)
  * Add missing commands to nodetool_completion (CASSANDRA-14916)
  * Anti-compaction temporarily corrupts sstable state for readers 
(CASSANDRA-15004)
- Merged from 2.2:
+Merged from 2.2:
  * Multi-version in-JVM dtests (CASSANDRA-14937)
 
 
@@ -43,7 +44,7 @@ Merged from 3.0:
  * Fix static column order for SELECT * wildcard queries (CASSANDRA-14638)
  * sstableloader should use discovered broadcast address to connect 
intra-cluster (CASSANDRA-14522)
  * Fix reading columns with non-UTF names from schema (CASSANDRA-14468)
- Merged from 2.2:
+Merged from 2.2:
  * CircleCI docker image should bake in more dependencies (CASSANDRA-14985)
  * Don't enable client transports when bootstrap is pending (CASSANDRA-14525)
  * MigrationManager attempts to pull schema from different major version nodes 
(CASSANDRA-14928)
diff --git a/NEWS.txt b/NEWS.txt
index d5a9128..2feac81 100644
--- a/NEWS.txt
+++ b/NEWS.txt
@@ -50,6 +50,14 @@ Upgrading
        - repair_session_max_tree_depth setting has been added to 
cassandra.yaml to allow operators to reduce
          merkle tree size if repair is creating too much heap pressure. See 
CASSANDRA-14096 for details.
 
+Experimental features
+---------------------
+    - An 'enable_sasi_indexes' flag, true by default, has been added to 
cassandra.yaml to allow operators to prevent
+      the creation of new SASI indexes, which are considered experimental and 
are not recommended for production use.
+      (See https://www.mail-archive.com/dev@cassandra.apache.org/msg13582.html)
+    - The flags 'enable_sasi_indexes' and 'enable_materialized_views' have 
been grouped under an experimental features
+      section in cassandra.yaml.
+
 3.11.4
 ======
 
diff --git a/conf/cassandra.yaml b/conf/cassandra.yaml
index a263d8a..9182008 100644
--- a/conf/cassandra.yaml
+++ b/conf/cassandra.yaml
@@ -1112,10 +1112,6 @@ enable_user_defined_functions: false
 # This option has no effect, if enable_user_defined_functions is false.
 enable_scripted_user_defined_functions: false
 
-# Enables materialized view creation on this node.
-# Materialized views are considered experimental and are not recommended for 
production use.
-enable_materialized_views: true
-
 # The default Windows kernel timer and scheduling resolution is 15.6ms for 
power conservation.
 # Lowering this value on Windows can provide much tighter latency and better 
throughput, however
 # some virtualized environments may see a negative performance impact from 
changing this setting
@@ -1247,4 +1243,17 @@ back_pressure_strategy:
 # time and queue contention while iterating the backlog of messages.
 # An interval of 0 disables any wait time, which is the behavior of former 
Cassandra versions.
 #
-# otc_backlog_expiration_interval_ms: 200
\ No newline at end of file
+# otc_backlog_expiration_interval_ms: 200
+
+
+#########################
+# EXPERIMENTAL FEATURES #
+#########################
+
+# Enables materialized view creation on this node.
+# Materialized views are considered experimental and are not recommended for 
production use.
+enable_materialized_views: true
+
+# Enables SASI index creation on this node.
+# SASI indexes are considered experimental and are not recommended for 
production use.
+enable_sasi_indexes: true
\ No newline at end of file
diff --git a/src/java/org/apache/cassandra/config/Config.java 
b/src/java/org/apache/cassandra/config/Config.java
index 528cf4f..1976b95 100644
--- a/src/java/org/apache/cassandra/config/Config.java
+++ b/src/java/org/apache/cassandra/config/Config.java
@@ -348,6 +348,8 @@ public class Config
 
     public boolean enable_materialized_views = true;
 
+    public boolean enable_sasi_indexes = true;
+
     /**
      * Optionally disable asynchronous UDF execution.
      * Disabling asynchronous UDF execution also implicitly disables the 
security-manager!
diff --git a/src/java/org/apache/cassandra/config/DatabaseDescriptor.java 
b/src/java/org/apache/cassandra/config/DatabaseDescriptor.java
index 069a17e..99f8575 100644
--- a/src/java/org/apache/cassandra/config/DatabaseDescriptor.java
+++ b/src/java/org/apache/cassandra/config/DatabaseDescriptor.java
@@ -2407,11 +2407,26 @@ public class DatabaseDescriptor
         conf.user_defined_function_warn_timeout = 
userDefinedFunctionWarnTimeout;
     }
 
-    public static boolean enableMaterializedViews()
+    public static boolean getEnableMaterializedViews()
     {
         return conf.enable_materialized_views;
     }
 
+    public static void setEnableMaterializedViews(boolean 
enableMaterializedViews)
+    {
+        conf.enable_materialized_views = enableMaterializedViews;
+    }
+
+    public static boolean getEnableSASIIndexes()
+    {
+        return conf.enable_sasi_indexes;
+    }
+
+    public static void setEnableSASIIndexes(boolean enableSASIIndexes)
+    {
+        conf.enable_sasi_indexes = enableSASIIndexes;
+    }
+
     public static long getUserDefinedFunctionFailTimeout()
     {
         return conf.user_defined_function_fail_timeout;
diff --git 
a/src/java/org/apache/cassandra/cql3/statements/CreateIndexStatement.java 
b/src/java/org/apache/cassandra/cql3/statements/CreateIndexStatement.java
index 88afc6b..d615917 100644
--- a/src/java/org/apache/cassandra/cql3/statements/CreateIndexStatement.java
+++ b/src/java/org/apache/cassandra/cql3/statements/CreateIndexStatement.java
@@ -29,18 +29,20 @@ import org.slf4j.LoggerFactory;
 import org.apache.cassandra.auth.Permission;
 import org.apache.cassandra.config.CFMetaData;
 import org.apache.cassandra.config.ColumnDefinition;
+import org.apache.cassandra.config.DatabaseDescriptor;
 import org.apache.cassandra.config.Schema;
 import org.apache.cassandra.cql3.CFName;
 import org.apache.cassandra.cql3.ColumnIdentifier;
 import org.apache.cassandra.cql3.IndexName;
-import org.apache.cassandra.db.marshal.DurationType;
 import org.apache.cassandra.db.marshal.MapType;
 import org.apache.cassandra.exceptions.InvalidRequestException;
 import org.apache.cassandra.exceptions.RequestValidationException;
 import org.apache.cassandra.exceptions.UnauthorizedException;
+import org.apache.cassandra.index.sasi.SASIIndex;
 import org.apache.cassandra.schema.IndexMetadata;
 import org.apache.cassandra.schema.Indexes;
 import org.apache.cassandra.service.ClientState;
+import org.apache.cassandra.service.ClientWarn;
 import org.apache.cassandra.service.MigrationManager;
 import org.apache.cassandra.service.QueryState;
 import org.apache.cassandra.thrift.ThriftValidation;
@@ -229,6 +231,17 @@ public class CreateIndexStatement extends 
SchemaAlteringStatement
         {
             kind = IndexMetadata.Kind.CUSTOM;
             indexOptions = properties.getOptions();
+
+            if (properties.customClass.equals(SASIIndex.class.getName()))
+            {
+                if (!DatabaseDescriptor.getEnableSASIIndexes())
+                    throw new InvalidRequestException("SASI indexes are 
disabled. Enable in cassandra.yaml to use.");
+
+                logger.warn("Creating SASI index {} for {}.{}. {}",
+                            acceptedName, cfm.ksName, cfm.cfName, 
SASIIndex.USAGE_WARNING);
+
+                ClientWarn.instance.warn(SASIIndex.USAGE_WARNING);
+            }
         }
         else
         {
diff --git 
a/src/java/org/apache/cassandra/cql3/statements/CreateViewStatement.java 
b/src/java/org/apache/cassandra/cql3/statements/CreateViewStatement.java
index c191fa1..51e0aaf 100644
--- a/src/java/org/apache/cassandra/cql3/statements/CreateViewStatement.java
+++ b/src/java/org/apache/cassandra/cql3/statements/CreateViewStatement.java
@@ -123,7 +123,7 @@ public class CreateViewStatement extends 
SchemaAlteringStatement
 
     public Event.SchemaChange announceMigration(QueryState queryState, boolean 
isLocalOnly) throws RequestValidationException
     {
-        if (!DatabaseDescriptor.enableMaterializedViews())
+        if (!DatabaseDescriptor.getEnableMaterializedViews())
         {
             throw new InvalidRequestException("Materialized views are 
disabled. Enable in cassandra.yaml to use.");
         }
@@ -327,13 +327,12 @@ public class CreateViewStatement extends 
SchemaAlteringStatement
                                                        whereClauseText,
                                                        viewCfm);
 
-        logger.warn("Creating materialized view {} for {}.{}. " +
-                    "Materialized views are experimental and are not 
recommended for production use.",
-                    definition.viewName, cfm.ksName, cfm.cfName);
+        logger.warn("Creating materialized view {} for {}.{}. {}",
+                    definition.viewName, cfm.ksName, cfm.cfName, 
View.USAGE_WARNING);
 
         try
         {
-            ClientWarn.instance.warn("Materialized views are experimental and 
are not recommended for production use.");
+            ClientWarn.instance.warn(View.USAGE_WARNING);
             MigrationManager.announceNewView(definition, isLocalOnly);
             return new Event.SchemaChange(Event.SchemaChange.Change.CREATED, 
Event.SchemaChange.Target.TABLE, keyspace(), columnFamily());
         }
diff --git a/src/java/org/apache/cassandra/db/view/View.java 
b/src/java/org/apache/cassandra/db/view/View.java
index 9a00b13..d7cd827 100644
--- a/src/java/org/apache/cassandra/db/view/View.java
+++ b/src/java/org/apache/cassandra/db/view/View.java
@@ -33,7 +33,6 @@ import org.apache.cassandra.config.CFMetaData;
 import org.apache.cassandra.config.ColumnDefinition;
 import org.apache.cassandra.config.Schema;
 import org.apache.cassandra.config.ViewDefinition;
-import org.apache.cassandra.cql3.ColumnIdentifier;
 import org.apache.cassandra.cql3.MultiColumnRelation;
 import org.apache.cassandra.cql3.QueryOptions;
 import org.apache.cassandra.cql3.Relation;
@@ -57,6 +56,8 @@ import org.apache.cassandra.utils.FBUtilities;
  */
 public class View
 {
+    public final static String USAGE_WARNING = "Materialized views are 
experimental and are not recommended for production use.";
+
     private static final Logger logger = LoggerFactory.getLogger(View.class);
 
     public final String name;
diff --git a/src/java/org/apache/cassandra/index/sasi/SASIIndex.java 
b/src/java/org/apache/cassandra/index/sasi/SASIIndex.java
index 2c1d088..4bf94ef 100644
--- a/src/java/org/apache/cassandra/index/sasi/SASIIndex.java
+++ b/src/java/org/apache/cassandra/index/sasi/SASIIndex.java
@@ -59,6 +59,8 @@ import org.apache.cassandra.utils.concurrent.OpOrder;
 
 public class SASIIndex implements Index, INotificationConsumer
 {
+    public final static String USAGE_WARNING = "SASI indexes are experimental 
and are not recommended for production use.";
+
     private static class SASIIndexBuildingSupport implements 
IndexBuildingSupport
     {
         public SecondaryIndexBuilder getIndexBuildTask(ColumnFamilyStore cfs,
diff --git a/test/unit/org/apache/cassandra/cql3/ViewTest.java 
b/test/unit/org/apache/cassandra/cql3/ViewTest.java
index eb9c855..8a98a8e 100644
--- a/test/unit/org/apache/cassandra/cql3/ViewTest.java
+++ b/test/unit/org/apache/cassandra/cql3/ViewTest.java
@@ -18,12 +18,9 @@
 
 package org.apache.cassandra.cql3;
 
-import static org.junit.Assert.*;
-
 import java.util.ArrayList;
 import java.util.HashSet;
 import java.util.List;
-import java.util.UUID;
 import java.util.concurrent.Future;
 import java.util.concurrent.TimeUnit;
 import com.google.common.util.concurrent.Uninterruptibles;
@@ -43,14 +40,16 @@ import org.apache.cassandra.concurrent.Stage;
 import org.apache.cassandra.concurrent.StageManager;
 import org.apache.cassandra.config.CFMetaData;
 import org.apache.cassandra.config.ColumnDefinition;
+import org.apache.cassandra.config.DatabaseDescriptor;
 import org.apache.cassandra.db.ColumnFamilyStore;
 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;
 
@@ -1421,4 +1420,52 @@ public class ViewTest extends CQLTester
      {
          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");
+        }
+        catch (Throwable e)
+        {
+            Assert.assertTrue(e instanceof InvalidQueryException);
+            Assert.assertTrue(e.getMessage().contains("Materialized views are 
disabled"));
+        }
+        finally
+        {
+            
DatabaseDescriptor.setEnableMaterializedViews(enableMaterializedViews);
+        }
+    }
 }
\ No newline at end of file
diff --git a/test/unit/org/apache/cassandra/index/sasi/SASICQLTest.java 
b/test/unit/org/apache/cassandra/index/sasi/SASICQLTest.java
index efef880..17bd196 100644
--- a/test/unit/org/apache/cassandra/index/sasi/SASICQLTest.java
+++ b/test/unit/org/apache/cassandra/index/sasi/SASICQLTest.java
@@ -28,7 +28,10 @@ import com.datastax.driver.core.Row;
 import com.datastax.driver.core.Session;
 import com.datastax.driver.core.SimpleStatement;
 import junit.framework.Assert;
+import org.apache.cassandra.config.DatabaseDescriptor;
 import org.apache.cassandra.cql3.CQLTester;
+import org.apache.cassandra.exceptions.InvalidRequestException;
+import org.apache.cassandra.service.ClientWarn;
 
 public class SASICQLTest extends CQLTester
 {
@@ -78,4 +81,49 @@ public class SASICQLTest extends CQLTester
             Assert.assertEquals(20, rs.size());
         }
     }
+
+    /**
+     * Tests that a client warning is issued on SASI index creation.
+     */
+    @Test
+    public void testClientWarningOnCreate()
+    {
+        createTable("CREATE TABLE %s (k int PRIMARY KEY, v int)");
+
+        ClientWarn.instance.captureWarnings();
+        createIndex("CREATE CUSTOM INDEX ON %s (v) USING 
'org.apache.cassandra.index.sasi.SASIIndex'");
+        List<String> warnings = ClientWarn.instance.getWarnings();
+
+        Assert.assertNotNull(warnings);
+        Assert.assertEquals(1, warnings.size());
+        Assert.assertEquals(SASIIndex.USAGE_WARNING, warnings.get(0));
+    }
+
+    /**
+     * Tests the configuration flag to disable SASI indexes.
+     */
+    @Test
+    public void testDisableSASIIndexes()
+    {
+        createTable("CREATE TABLE %s (k int PRIMARY KEY, v int)");
+
+        boolean enableSASIIndexes = DatabaseDescriptor.getEnableSASIIndexes();
+        try
+        {
+            DatabaseDescriptor.setEnableSASIIndexes(false);
+            createIndex("CREATE CUSTOM INDEX ON %s (v) USING 
'org.apache.cassandra.index.sasi.SASIIndex'");
+            Assert.fail("Should not be able to create a SASI index if they are 
disabled");
+        }
+        catch (RuntimeException e)
+        {
+            Throwable cause = e.getCause();
+            Assert.assertNotNull(cause);
+            Assert.assertTrue(cause instanceof InvalidRequestException);
+            Assert.assertTrue(cause.getMessage().contains("SASI indexes are 
disabled"));
+        }
+        finally
+        {
+            DatabaseDescriptor.setEnableSASIIndexes(enableSASIIndexes);
+        }
+    }
 }


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

Reply via email to