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 <[email protected]>
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/[email protected]/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: [email protected]
For additional commands, e-mail: [email protected]