You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cassandra.apache.org by if...@apache.org on 2017/11/06 15:50:16 UTC
[06/25] cassandra git commit: Allow dropping COMPACT STORAGE flag
Allow dropping COMPACT STORAGE flag
Patch by Alex Petrov; reviewed by Sylvain Lebresne for CASSANDRA-10857.
Project: http://git-wip-us.apache.org/repos/asf/cassandra/repo
Commit: http://git-wip-us.apache.org/repos/asf/cassandra/commit/6c29ee84
Tree: http://git-wip-us.apache.org/repos/asf/cassandra/tree/6c29ee84
Diff: http://git-wip-us.apache.org/repos/asf/cassandra/diff/6c29ee84
Branch: refs/heads/trunk
Commit: 6c29ee84a2f62ccd05c328bbaa0c364eb1a7a821
Parents: b869744
Author: Alex Petrov <ol...@gmail.com>
Authored: Sat Sep 30 08:56:22 2017 +0200
Committer: Alex Petrov <ol...@gmail.com>
Committed: Mon Nov 6 15:44:51 2017 +0100
----------------------------------------------------------------------
NEWS.txt | 17 +
bin/cqlsh.py | 6 +-
doc/native_protocol_v4.spec | 4 +
...dra-driver-internal-only-3.11.0-bb96859b.zip | Bin 0 -> 266661 bytes
...driver-internal-only-3.7.1.post0-19c1603.zip | Bin 252027 -> 0 bytes
.../cassandra/auth/CassandraRoleManager.java | 3 +-
.../org/apache/cassandra/config/CFMetaData.java | 59 ++-
src/java/org/apache/cassandra/cql3/Cql.g | 27 +-
.../apache/cassandra/cql3/QueryProcessor.java | 2 +-
.../cql3/statements/AlterTableStatement.java | 42 +-
.../statements/AuthenticationStatement.java | 2 +-
.../cql3/statements/AuthorizationStatement.java | 2 +-
.../cql3/statements/BatchStatement.java | 4 +-
.../statements/CreateAggregateStatement.java | 4 +-
.../statements/CreateFunctionStatement.java | 4 +-
.../cql3/statements/CreateIndexStatement.java | 9 +-
.../cql3/statements/CreateTableStatement.java | 2 +-
.../cql3/statements/CreateViewStatement.java | 2 +-
.../cql3/statements/DropFunctionStatement.java | 4 +-
.../cql3/statements/ModificationStatement.java | 11 +-
.../cql3/statements/ParsedStatement.java | 3 +-
.../statements/SchemaAlteringStatement.java | 32 +-
.../cql3/statements/SelectStatement.java | 8 +-
.../cql3/statements/TruncateStatement.java | 2 +-
.../cassandra/cql3/statements/UseStatement.java | 2 +-
src/java/org/apache/cassandra/db/view/View.java | 38 +-
.../index/internal/keys/KeysSearcher.java | 8 +-
.../apache/cassandra/repair/RepairRunnable.java | 3 +-
.../apache/cassandra/service/ClientState.java | 16 +
.../cassandra/thrift/ThriftValidation.java | 10 +-
.../transport/messages/StartupMessage.java | 4 +
.../org/apache/cassandra/cql3/ViewTest.java | 15 +-
.../cql3/validation/entities/UFTest.java | 25 +
.../cql3/validation/entities/UserTypesTest.java | 20 +
.../cql3/validation/operations/AlterTest.java | 15 +-
.../DropCompactStorageThriftTest.java | 525 +++++++++++++++++++
36 files changed, 843 insertions(+), 87 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/cassandra/blob/6c29ee84/NEWS.txt
----------------------------------------------------------------------
diff --git a/NEWS.txt b/NEWS.txt
index 60cf77c..621866b 100644
--- a/NEWS.txt
+++ b/NEWS.txt
@@ -37,6 +37,23 @@ Upgrading
- Nothing specific to this release, but please see previous upgrading sections,
especially if you are upgrading from 2.2.
+Compact Storage
+---------------
+ - Starting version 4.0, Thrift and COMPACT STORAGE is no longer supported.
+ 'ALTER ... DROP COMPACT STORAGE' statement makes Compact Tables CQL-compatible,
+ exposing internal structure of Thrift/Compact Tables. You can find more details
+ on exposed internal structure under:
+ http://cassandra.apache.org/doc/latest/cql/appendices.html#appendix-c-dropping-compact-storage
+
+ For uninterrupted cluster upgrades, drivers now support 'NO_COMPACT' startup option.
+ Supplying this flag will have same effect as 'DROP COMPACT STORAGE', but only for the
+ current connection.
+
+ In order to upgrade, clients supporting a non-compact schema view can be rolled out
+ gradually. When all the clients are updated 'ALTER ... DROP COMPACT STORAGE' can be
+ executed. After dropping compact storage, ’NO_COMPACT' option will have no effect
+ after that.
+
Materialized Views
-------------------
- Cassandra will no longer allow dropping columns on tables with Materialized Views.
http://git-wip-us.apache.org/repos/asf/cassandra/blob/6c29ee84/bin/cqlsh.py
----------------------------------------------------------------------
diff --git a/bin/cqlsh.py b/bin/cqlsh.py
index 8eb42a3..8d05d9d 100644
--- a/bin/cqlsh.py
+++ b/bin/cqlsh.py
@@ -205,6 +205,7 @@ parser.add_option("--browser", dest='browser', help="""The browser to use to dis
- one of the supported browsers in https://docs.python.org/2/library/webbrowser.html.
- browser path followed by %s, example: /usr/bin/google-chrome-stable %s""")
parser.add_option('--ssl', action='store_true', help='Use SSL', default=False)
+parser.add_option('--no_compact', action='store_true', help='No Compact', default=False)
parser.add_option("-u", "--username", help="Authenticate as user.")
parser.add_option("-p", "--password", help="Authenticate using password.")
parser.add_option('-k', '--keyspace', help='Authenticate to the given keyspace.')
@@ -702,6 +703,7 @@ class Shell(cmd.Cmd):
completekey=DEFAULT_COMPLETEKEY, browser=None, use_conn=None,
cqlver=DEFAULT_CQLVER, keyspace=None,
tracing_enabled=False, expand_enabled=False,
+ no_compact=False,
display_nanotime_format=DEFAULT_NANOTIME_FORMAT,
display_timestamp_format=DEFAULT_TIMESTAMP_FORMAT,
display_date_format=DEFAULT_DATE_FORMAT,
@@ -732,7 +734,7 @@ class Shell(cmd.Cmd):
else:
self.conn = Cluster(contact_points=(self.hostname,), port=self.port, cql_version=cqlver,
protocol_version=protocol_version,
- auth_provider=self.auth_provider,
+ auth_provider=self.auth_provider, no_compact=no_compact,
ssl_options=sslhandling.ssl_settings(hostname, CONFIG_FILE) if ssl else None,
load_balancing_policy=WhiteListRoundRobinPolicy([self.hostname]),
control_connection_timeout=connect_timeout,
@@ -2486,6 +2488,7 @@ def read_options(cmdlineargs, environment):
optvalues.debug = False
optvalues.file = None
optvalues.ssl = False
+ optvalues.no_compact = False
optvalues.encoding = option_with_default(configs.get, 'ui', 'encoding', UTF8)
optvalues.tty = option_with_default(configs.getboolean, 'ui', 'tty', sys.stdin.isatty())
@@ -2643,6 +2646,7 @@ def main(options, hostname, port):
browser=options.browser,
cqlver=options.cqlversion,
keyspace=options.keyspace,
+ no_compact=options.no_compact,
display_timestamp_format=options.time_format,
display_nanotime_format=options.nanotime_format,
display_date_format=options.date_format,
http://git-wip-us.apache.org/repos/asf/cassandra/blob/6c29ee84/doc/native_protocol_v4.spec
----------------------------------------------------------------------
diff --git a/doc/native_protocol_v4.spec b/doc/native_protocol_v4.spec
index 44dac18..2188a33 100644
--- a/doc/native_protocol_v4.spec
+++ b/doc/native_protocol_v4.spec
@@ -271,6 +271,10 @@ Table of Contents
different from the protocol version.
- "COMPRESSION": the compression algorithm to use for frames (See section 5).
This is optional; if not specified no compression will be used.
+ - "NO_COMPACT": whether or not connection has to be established in compatibility
+ mode. This mode will make all Thrift and Compact Tables to be exposed as if
+ they were CQL Tables. This is optional; if not specified, the option will
+ not be used.
4.1.2. AUTH_RESPONSE
http://git-wip-us.apache.org/repos/asf/cassandra/blob/6c29ee84/lib/cassandra-driver-internal-only-3.11.0-bb96859b.zip
----------------------------------------------------------------------
diff --git a/lib/cassandra-driver-internal-only-3.11.0-bb96859b.zip b/lib/cassandra-driver-internal-only-3.11.0-bb96859b.zip
new file mode 100644
index 0000000..d31abc3
Binary files /dev/null and b/lib/cassandra-driver-internal-only-3.11.0-bb96859b.zip differ
http://git-wip-us.apache.org/repos/asf/cassandra/blob/6c29ee84/lib/cassandra-driver-internal-only-3.7.1.post0-19c1603.zip
----------------------------------------------------------------------
diff --git a/lib/cassandra-driver-internal-only-3.7.1.post0-19c1603.zip b/lib/cassandra-driver-internal-only-3.7.1.post0-19c1603.zip
deleted file mode 100644
index 900d64d..0000000
Binary files a/lib/cassandra-driver-internal-only-3.7.1.post0-19c1603.zip and /dev/null differ
http://git-wip-us.apache.org/repos/asf/cassandra/blob/6c29ee84/src/java/org/apache/cassandra/auth/CassandraRoleManager.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/auth/CassandraRoleManager.java b/src/java/org/apache/cassandra/auth/CassandraRoleManager.java
index e5b98e4..c6716e5 100644
--- a/src/java/org/apache/cassandra/auth/CassandraRoleManager.java
+++ b/src/java/org/apache/cassandra/auth/CassandraRoleManager.java
@@ -39,6 +39,7 @@ import org.apache.cassandra.db.ConsistencyLevel;
import org.apache.cassandra.db.marshal.UTF8Type;
import org.apache.cassandra.exceptions.*;
import org.apache.cassandra.net.MessagingService;
+import org.apache.cassandra.service.ClientState;
import org.apache.cassandra.service.QueryState;
import org.apache.cassandra.service.StorageService;
import org.apache.cassandra.transport.messages.ResultMessage;
@@ -465,7 +466,7 @@ public class CassandraRoleManager implements IRoleManager
{
try
{
- return QueryProcessor.parseStatement(String.format(template, keyspace, table)).prepare().statement;
+ return QueryProcessor.parseStatement(String.format(template, keyspace, table)).prepare(ClientState.forInternalCalls()).statement;
}
catch (RequestValidationException e)
{
http://git-wip-us.apache.org/repos/asf/cassandra/blob/6c29ee84/src/java/org/apache/cassandra/config/CFMetaData.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/config/CFMetaData.java b/src/java/org/apache/cassandra/config/CFMetaData.java
index fd1c9e5..c1b2171 100644
--- a/src/java/org/apache/cassandra/config/CFMetaData.java
+++ b/src/java/org/apache/cassandra/config/CFMetaData.java
@@ -79,10 +79,6 @@ public final class CFMetaData
public final Pair<String, String> ksAndCFName;
public final byte[] ksAndCFBytes;
- private final ImmutableSet<Flag> flags;
- private final boolean isDense;
- private final boolean isCompound;
- private final boolean isSuper;
private final boolean isCounter;
private final boolean isView;
private final boolean isIndex;
@@ -94,6 +90,11 @@ public final class CFMetaData
private final Serializers serializers;
// non-final, for now
+ private volatile ImmutableSet<Flag> flags;
+ private volatile boolean isDense;
+ private volatile boolean isCompound;
+ private volatile boolean isSuper;
+
public volatile TableParams params = TableParams.DEFAULT;
private volatile Map<ByteBuffer, DroppedColumn> droppedColumns = new HashMap<>();
@@ -127,6 +128,9 @@ public final class CFMetaData
private volatile ColumnDefinition superCfKeyColumn;
private volatile ColumnDefinition superCfValueColumn;
+ /** Caches a non-compact version of the metadata for compact tables to be used with the NO_COMPACT protocol option. */
+ private volatile CFMetaData nonCompactCopy = null;
+
public boolean isSuperColumnKeyColumn(ColumnDefinition cd)
{
return cd.name.equals(superCfKeyColumn.name);
@@ -330,6 +334,9 @@ public final class CFMetaData
// are kept because they are often useful in a different format.
private void rebuild()
{
+ // A non-compact copy will be created lazily
+ this.nonCompactCopy = null;
+
if (isCompactTable())
{
this.compactValueColumn = isSuper() ?
@@ -505,6 +512,38 @@ public final class CFMetaData
return params(indexParams.build());
}
+ /**
+ * Returns a cached non-compact version of this table. Cached version has to be invalidated
+ * every time the table is rebuilt.
+ */
+ public CFMetaData asNonCompact()
+ {
+ assert isCompactTable() : "Can't get non-compact version of a CQL table";
+
+ // Note that this is racy, but re-computing the non-compact copy a few times on first uses isn't a big deal so
+ // we don't bother.
+ if (nonCompactCopy == null)
+ {
+ nonCompactCopy = copyOpts(new CFMetaData(ksName,
+ cfName,
+ cfId,
+ false,
+ isCounter,
+ false,
+ true,
+ isView,
+ copy(partitionKeyColumns),
+ copy(clusteringColumns),
+ copy(partitionColumns),
+ partitioner,
+ superCfKeyColumn,
+ superCfValueColumn),
+ this);
+ }
+
+ return nonCompactCopy;
+ }
+
public CFMetaData copy()
{
return copy(cfId);
@@ -842,6 +881,12 @@ public final class CFMetaData
superCfKeyColumn = cfm.superCfKeyColumn;
superCfValueColumn = cfm.superCfValueColumn;
+ isDense = cfm.isDense;
+ isCompound = cfm.isCompound;
+ isSuper = cfm.isSuper;
+
+ flags = cfm.flags;
+
rebuild();
// compaction thresholds are checked by ThriftValidation. We shouldn't be doing
@@ -874,12 +919,6 @@ public final class CFMetaData
if (!cfm.cfId.equals(cfId))
throw new ConfigurationException(String.format("Column family ID mismatch (found %s; expected %s)",
cfm.cfId, cfId));
-
- // Dense flag can get set, see CASSANDRA-12373 for details. We have to remove flag from both parts because
- // there's no guaranteed call order in the call.
-
- if (!cfm.flags.equals(flags) && (!isSuper() || !Sets.difference(cfm.flags, Sets.immutableEnumSet(Flag.DENSE)).equals(Sets.difference(flags, Sets.immutableEnumSet(Flag.DENSE)))))
- throw new ConfigurationException("Types do not match: " + cfm.flags + " != " + flags);
}
http://git-wip-us.apache.org/repos/asf/cassandra/blob/6c29ee84/src/java/org/apache/cassandra/cql3/Cql.g
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/cql3/Cql.g b/src/java/org/apache/cassandra/cql3/Cql.g
index 3123877..0234327 100644
--- a/src/java/org/apache/cassandra/cql3/Cql.g
+++ b/src/java/org/apache/cassandra/cql3/Cql.g
@@ -781,7 +781,7 @@ createTriggerStatement returns [CreateTriggerStatement expr]
@init {
boolean ifNotExists = false;
}
- : K_CREATE K_TRIGGER (K_IF K_NOT K_EXISTS { ifNotExists = true; } )? (name=cident)
+ : K_CREATE K_TRIGGER (K_IF K_NOT K_EXISTS { ifNotExists = true; } )? (name=noncol_ident)
K_ON cf=columnFamilyName K_USING cls=STRING_LITERAL
{ $expr = new CreateTriggerStatement(cf, name.toString(), $cls.text, ifNotExists); }
;
@@ -791,7 +791,7 @@ createTriggerStatement returns [CreateTriggerStatement expr]
*/
dropTriggerStatement returns [DropTriggerStatement expr]
@init { boolean ifExists = false; }
- : K_DROP K_TRIGGER (K_IF K_EXISTS { ifExists = true; } )? (name=cident) K_ON cf=columnFamilyName
+ : K_DROP K_TRIGGER (K_IF K_EXISTS { ifExists = true; } )? (name=noncol_ident) K_ON cf=columnFamilyName
{ $expr = new DropTriggerStatement(cf, name.toString(), ifExists); }
;
@@ -816,20 +816,21 @@ alterTableStatement returns [AlterTableStatement expr]
@init {
AlterTableStatement.Type type = null;
TableAttributes attrs = new TableAttributes();
- Map<ColumnIdentifier.Raw, ColumnIdentifier.Raw> renames = new HashMap<ColumnIdentifier.Raw, ColumnIdentifier.Raw>();
+ Map<ColumnIdentifier.Raw, ColumnIdentifier> renames = new HashMap<ColumnIdentifier.Raw, ColumnIdentifier>();
boolean isStatic = false;
Long dropTimestamp = null;
}
: K_ALTER K_COLUMNFAMILY cf=columnFamilyName
- ( K_ALTER id=cident K_TYPE v=comparatorType { type = AlterTableStatement.Type.ALTER; }
- | K_ADD id=cident v=comparatorType ({ isStatic=true; } K_STATIC)? { type = AlterTableStatement.Type.ADD; }
+ ( K_ALTER id=cident K_TYPE v=comparatorType { type = AlterTableStatement.Type.ALTER; }
+ | K_ADD aid=ident {id=new ColumnIdentifier.ColumnIdentifierValue(aid);} v=comparatorType ({ isStatic=true; } K_STATIC)? { type = AlterTableStatement.Type.ADD; }
| K_DROP id=cident { type = AlterTableStatement.Type.DROP; }
| K_DROP id=cident K_USING K_TIMESTAMP t=INTEGER { type = AlterTableStatement.Type.DROP;
dropTimestamp = Long.parseLong(Constants.Literal.integer($t.text).getText()); }
+ | K_DROP K_COMPACT K_STORAGE { type = AlterTableStatement.Type.DROP_COMPACT_STORAGE; }
| K_WITH properties[attrs] { type = AlterTableStatement.Type.OPTS; }
| K_RENAME { type = AlterTableStatement.Type.RENAME; }
- id1=cident K_TO toId1=cident { renames.put(id1, toId1); }
- ( K_AND idn=cident K_TO toIdn=cident { renames.put(idn, toIdn); } )*
+ id1=cident K_TO toId1=ident { renames.put(id1, toId1); }
+ ( K_AND idn=cident K_TO toIdn=ident { renames.put(idn, toIdn); } )*
)
{
$expr = new AlterTableStatement(cf, type, id, v, attrs, renames, isStatic, dropTimestamp);
@@ -1169,10 +1170,14 @@ userPassword[RoleOptions opts]
// Column Identifiers. These need to be treated differently from other
// identifiers because the underlying comparator is not necessarily text. See
// CASSANDRA-8178 for details.
+// Also, we need to support the internal of the super column map (for backward
+// compatibility) which is empty (we only want to allow this is queries, not for
+// creating table or other).
cident returns [ColumnIdentifier.Raw id]
: t=IDENT { $id = new ColumnIdentifier.Literal($t.text, false); }
| t=QUOTED_NAME { $id = new ColumnIdentifier.Literal($t.text, true); }
| k=unreserved_keyword { $id = new ColumnIdentifier.Literal(k, false); }
+ | EMPTY_QUOTED_NAME { $id = new ColumnIdentifier.Literal("", false); }
;
// Column identifiers where the comparator is known to be text
@@ -1309,7 +1314,9 @@ intValue returns [Term.Raw value]
;
functionName returns [FunctionName s]
- : (ks=keyspaceName '.')? f=allowedFunctionName { $s = new FunctionName(ks, f); }
+ // antlr might try to recover and give a null for f. It will still error out in the end, but FunctionName
+ // wouldn't be happy with that so we should bypass this for now or we'll have a weird user-facing error
+ : (ks=keyspaceName '.')? f=allowedFunctionName { $s = f == null ? null : new FunctionName(ks, f); }
;
allowedFunctionName returns [String s]
@@ -1822,6 +1829,10 @@ STRING_LITERAL
)
;
+EMPTY_QUOTED_NAME
+ : '\"' '\"'
+ ;
+
QUOTED_NAME
@init{ StringBuilder b = new StringBuilder(); }
@after{ setText(b.toString()); }
http://git-wip-us.apache.org/repos/asf/cassandra/blob/6c29ee84/src/java/org/apache/cassandra/cql3/QueryProcessor.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/cql3/QueryProcessor.java b/src/java/org/apache/cassandra/cql3/QueryProcessor.java
index af94d3e..ddee6c7 100644
--- a/src/java/org/apache/cassandra/cql3/QueryProcessor.java
+++ b/src/java/org/apache/cassandra/cql3/QueryProcessor.java
@@ -517,7 +517,7 @@ public class QueryProcessor implements QueryHandler
((CFStatement)statement).prepareKeyspace(clientState);
Tracing.trace("Preparing statement");
- return statement.prepare();
+ return statement.prepare(clientState);
}
public static ParsedStatement parseStatement(String queryStr) throws SyntaxException
http://git-wip-us.apache.org/repos/asf/cassandra/blob/6c29ee84/src/java/org/apache/cassandra/cql3/statements/AlterTableStatement.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/cql3/statements/AlterTableStatement.java b/src/java/org/apache/cassandra/cql3/statements/AlterTableStatement.java
index befdd25..a5fa12d 100644
--- a/src/java/org/apache/cassandra/cql3/statements/AlterTableStatement.java
+++ b/src/java/org/apache/cassandra/cql3/statements/AlterTableStatement.java
@@ -31,8 +31,6 @@ import org.apache.cassandra.db.ColumnFamilyStore;
import org.apache.cassandra.db.Keyspace;
import org.apache.cassandra.db.marshal.AbstractType;
import org.apache.cassandra.db.marshal.CollectionType;
-import org.apache.cassandra.db.marshal.CounterColumnType;
-import org.apache.cassandra.db.marshal.ReversedType;
import org.apache.cassandra.db.view.View;
import org.apache.cassandra.exceptions.*;
import org.apache.cassandra.schema.IndexMetadata;
@@ -49,14 +47,14 @@ public class AlterTableStatement extends SchemaAlteringStatement
{
public enum Type
{
- ADD, ALTER, DROP, OPTS, RENAME
+ ADD, ALTER, DROP, DROP_COMPACT_STORAGE, OPTS, RENAME
}
public final Type oType;
public final CQL3Type.Raw validator;
public final ColumnIdentifier.Raw rawColumnName;
private final TableAttributes attrs;
- private final Map<ColumnIdentifier.Raw, ColumnIdentifier.Raw> renames;
+ private final Map<ColumnIdentifier.Raw, ColumnIdentifier> renames;
private final boolean isStatic; // Only for ALTER ADD
private final Long deleteTimestamp;
@@ -65,7 +63,7 @@ public class AlterTableStatement extends SchemaAlteringStatement
ColumnIdentifier.Raw columnName,
CQL3Type.Raw validator,
TableAttributes attrs,
- Map<ColumnIdentifier.Raw, ColumnIdentifier.Raw> renames,
+ Map<ColumnIdentifier.Raw, ColumnIdentifier> renames,
boolean isStatic,
Long deleteTimestamp)
{
@@ -95,15 +93,15 @@ public class AlterTableStatement extends SchemaAlteringStatement
if (meta.isView())
throw new InvalidRequestException("Cannot use ALTER TABLE on Materialized View");
- CFMetaData cfm = meta.copy();
+ CFMetaData cfm;
CQL3Type validator = this.validator == null ? null : this.validator.prepare(keyspace());
ColumnIdentifier columnName = null;
ColumnDefinition def = null;
if (rawColumnName != null)
{
- columnName = rawColumnName.prepare(cfm);
- def = cfm.getColumnDefinition(columnName);
+ columnName = rawColumnName.prepare(meta);
+ def = meta.getColumnDefinition(columnName);
}
List<ViewDefinition> viewUpdates = null;
@@ -115,9 +113,11 @@ public class AlterTableStatement extends SchemaAlteringStatement
throw new InvalidRequestException("Altering of types is not allowed");
case ADD:
assert columnName != null;
- if (cfm.isDense())
+ if (meta.isDense())
throw new InvalidRequestException("Cannot add new column to a COMPACT STORAGE table");
+ cfm = meta.copy();
+
if (isStatic)
{
if (!cfm.isCompound())
@@ -190,11 +190,14 @@ public class AlterTableStatement extends SchemaAlteringStatement
case DROP:
assert columnName != null;
- if (!cfm.isCQLTable())
+ if (!meta.isCQLTable())
throw new InvalidRequestException("Cannot drop columns from a non-CQL3 table");
+
if (def == null)
throw new InvalidRequestException(String.format("Column %s was not found in table %s", columnName, columnFamily()));
+ cfm = meta.copy();
+
switch (def.kind)
{
case PARTITION_KEY:
@@ -238,11 +241,19 @@ public class AlterTableStatement extends SchemaAlteringStatement
columnName.toString(),
keyspace()));
break;
+ case DROP_COMPACT_STORAGE:
+ if (!meta.isCompactTable())
+ throw new InvalidRequestException("Cannot DROP COMPACT STORAGE on table without COMPACT STORAGE");
+
+ cfm = meta.asNonCompact();
+ break;
case OPTS:
if (attrs == null)
throw new InvalidRequestException("ALTER TABLE WITH invoked, but no parameters found");
attrs.validate();
+ cfm = meta.copy();
+
TableParams params = attrs.asAlteredTableParams(cfm.params);
if (!Iterables.isEmpty(views) && params.gcGraceSeconds == 0)
@@ -261,10 +272,13 @@ public class AlterTableStatement extends SchemaAlteringStatement
break;
case RENAME:
- for (Map.Entry<ColumnIdentifier.Raw, ColumnIdentifier.Raw> entry : renames.entrySet())
+ cfm = meta.copy();
+
+ for (Map.Entry<ColumnIdentifier.Raw, ColumnIdentifier> entry : renames.entrySet())
{
ColumnIdentifier from = entry.getKey().prepare(cfm);
- ColumnIdentifier to = entry.getValue().prepare(cfm);
+ ColumnIdentifier to = entry.getValue();
+
cfm.renameColumn(from, to);
// If the view includes a renamed column, it must be renamed in the view table and the definition.
@@ -274,7 +288,7 @@ public class AlterTableStatement extends SchemaAlteringStatement
ViewDefinition viewCopy = view.copy();
ColumnIdentifier viewFrom = entry.getKey().prepare(viewCopy.metadata);
- ColumnIdentifier viewTo = entry.getValue().prepare(viewCopy.metadata);
+ ColumnIdentifier viewTo = entry.getValue();
viewCopy.renameColumn(viewFrom, viewTo);
if (viewUpdates == null)
@@ -283,6 +297,8 @@ public class AlterTableStatement extends SchemaAlteringStatement
}
}
break;
+ default:
+ throw new InvalidRequestException("Can not alter table: unknown option type " + oType);
}
MigrationManager.announceColumnFamilyUpdate(cfm, viewUpdates, isLocalOnly);
http://git-wip-us.apache.org/repos/asf/cassandra/blob/6c29ee84/src/java/org/apache/cassandra/cql3/statements/AuthenticationStatement.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/cql3/statements/AuthenticationStatement.java b/src/java/org/apache/cassandra/cql3/statements/AuthenticationStatement.java
index 151e4f0..30ab6b0 100644
--- a/src/java/org/apache/cassandra/cql3/statements/AuthenticationStatement.java
+++ b/src/java/org/apache/cassandra/cql3/statements/AuthenticationStatement.java
@@ -31,7 +31,7 @@ import org.apache.cassandra.transport.messages.ResultMessage;
public abstract class AuthenticationStatement extends ParsedStatement implements CQLStatement
{
@Override
- public Prepared prepare()
+ public Prepared prepare(ClientState clientState)
{
return new Prepared(this);
}
http://git-wip-us.apache.org/repos/asf/cassandra/blob/6c29ee84/src/java/org/apache/cassandra/cql3/statements/AuthorizationStatement.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/cql3/statements/AuthorizationStatement.java b/src/java/org/apache/cassandra/cql3/statements/AuthorizationStatement.java
index 098e22c..fa2a993 100644
--- a/src/java/org/apache/cassandra/cql3/statements/AuthorizationStatement.java
+++ b/src/java/org/apache/cassandra/cql3/statements/AuthorizationStatement.java
@@ -32,7 +32,7 @@ import org.apache.cassandra.transport.messages.ResultMessage;
public abstract class AuthorizationStatement extends ParsedStatement implements CQLStatement
{
@Override
- public Prepared prepare()
+ public Prepared prepare(ClientState clientState)
{
return new Prepared(this);
}
http://git-wip-us.apache.org/repos/asf/cassandra/blob/6c29ee84/src/java/org/apache/cassandra/cql3/statements/BatchStatement.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/cql3/statements/BatchStatement.java b/src/java/org/apache/cassandra/cql3/statements/BatchStatement.java
index cd9358c..1c3cfa6 100644
--- a/src/java/org/apache/cassandra/cql3/statements/BatchStatement.java
+++ b/src/java/org/apache/cassandra/cql3/statements/BatchStatement.java
@@ -516,7 +516,7 @@ public class BatchStatement implements CQLStatement
statement.prepareKeyspace(state);
}
- public ParsedStatement.Prepared prepare() throws InvalidRequestException
+ public ParsedStatement.Prepared prepare(ClientState clientState) throws InvalidRequestException
{
VariableSpecifications boundNames = getBoundVariables();
@@ -537,7 +537,7 @@ public class BatchStatement implements CQLStatement
haveMultipleCFs = !firstKS.equals(parsed.keyspace()) || !firstCF.equals(parsed.columnFamily());
}
- statements.add(parsed.prepare(boundNames));
+ statements.add(parsed.prepare(boundNames, clientState));
}
Attributes prepAttrs = attrs.prepare("[batch]", "[batch]");
http://git-wip-us.apache.org/repos/asf/cassandra/blob/6c29ee84/src/java/org/apache/cassandra/cql3/statements/CreateAggregateStatement.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/cql3/statements/CreateAggregateStatement.java b/src/java/org/apache/cassandra/cql3/statements/CreateAggregateStatement.java
index ca0270f..9d91693 100644
--- a/src/java/org/apache/cassandra/cql3/statements/CreateAggregateStatement.java
+++ b/src/java/org/apache/cassandra/cql3/statements/CreateAggregateStatement.java
@@ -78,7 +78,7 @@ public final class CreateAggregateStatement extends SchemaAlteringStatement
this.ifNotExists = ifNotExists;
}
- public Prepared prepare()
+ public Prepared prepare(ClientState clientState)
{
argTypes = new ArrayList<>(argRawTypes.size());
for (CQL3Type.Raw rawType : argRawTypes)
@@ -136,7 +136,7 @@ public final class CreateAggregateStatement extends SchemaAlteringStatement
throw new InvalidRequestException("INITCOND must not be empty for all types except TEXT, ASCII, BLOB");
}
- return super.prepare();
+ return super.prepare(clientState);
}
private AbstractType<?> prepareType(String typeName, CQL3Type.Raw rawType)
http://git-wip-us.apache.org/repos/asf/cassandra/blob/6c29ee84/src/java/org/apache/cassandra/cql3/statements/CreateFunctionStatement.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/cql3/statements/CreateFunctionStatement.java b/src/java/org/apache/cassandra/cql3/statements/CreateFunctionStatement.java
index c8d38f5..dfe522b 100644
--- a/src/java/org/apache/cassandra/cql3/statements/CreateFunctionStatement.java
+++ b/src/java/org/apache/cassandra/cql3/statements/CreateFunctionStatement.java
@@ -76,7 +76,7 @@ public final class CreateFunctionStatement extends SchemaAlteringStatement
this.ifNotExists = ifNotExists;
}
- public Prepared prepare() throws InvalidRequestException
+ public Prepared prepare(ClientState clientState) throws InvalidRequestException
{
if (new HashSet<>(argNames).size() != argNames.size())
throw new InvalidRequestException(String.format("duplicate argument names for given function %s with argument names %s",
@@ -87,7 +87,7 @@ public final class CreateFunctionStatement extends SchemaAlteringStatement
argTypes.add(prepareType("arguments", rawType));
returnType = prepareType("return type", rawReturnType);
- return super.prepare();
+ return super.prepare(clientState);
}
public void prepareKeyspace(ClientState state) throws InvalidRequestException
http://git-wip-us.apache.org/repos/asf/cassandra/blob/6c29ee84/src/java/org/apache/cassandra/cql3/statements/CreateIndexStatement.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/cql3/statements/CreateIndexStatement.java b/src/java/org/apache/cassandra/cql3/statements/CreateIndexStatement.java
index c21441c..47d54fe 100644
--- a/src/java/org/apache/cassandra/cql3/statements/CreateIndexStatement.java
+++ b/src/java/org/apache/cassandra/cql3/statements/CreateIndexStatement.java
@@ -103,8 +103,13 @@ public class CreateIndexStatement extends SchemaAlteringStatement
throw new InvalidRequestException("No column definition found for column " + target.column);
// TODO: we could lift that limitation
- if (cfm.isCompactTable() && cd.isPrimaryKeyColumn())
- throw new InvalidRequestException("Secondary indexes are not supported on PRIMARY KEY columns in COMPACT STORAGE tables");
+ if (cfm.isCompactTable())
+ {
+ if (cd.isPrimaryKeyColumn())
+ throw new InvalidRequestException("Secondary indexes are not supported on PRIMARY KEY columns in COMPACT STORAGE tables");
+ if (cfm.compactValueColumn().equals(cd))
+ throw new InvalidRequestException("Secondary indexes are not supported on compact value column of COMPACT STORAGE tables");
+ }
// It would be possible to support 2ndary index on static columns (but not without modifications of at least ExtendedFilter and
// CompositesIndex) and maybe we should, but that means a query like:
http://git-wip-us.apache.org/repos/asf/cassandra/blob/6c29ee84/src/java/org/apache/cassandra/cql3/statements/CreateTableStatement.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/cql3/statements/CreateTableStatement.java b/src/java/org/apache/cassandra/cql3/statements/CreateTableStatement.java
index ef950dc..9f14194 100644
--- a/src/java/org/apache/cassandra/cql3/statements/CreateTableStatement.java
+++ b/src/java/org/apache/cassandra/cql3/statements/CreateTableStatement.java
@@ -191,7 +191,7 @@ public class CreateTableStatement extends SchemaAlteringStatement
/**
* Transform this raw statement into a CreateTableStatement.
*/
- public ParsedStatement.Prepared prepare() throws RequestValidationException
+ public ParsedStatement.Prepared prepare(ClientState clientState) throws RequestValidationException
{
KeyspaceMetadata ksm = Schema.instance.getKSMetaData(keyspace());
if (ksm == null)
http://git-wip-us.apache.org/repos/asf/cassandra/blob/6c29ee84/src/java/org/apache/cassandra/cql3/statements/CreateViewStatement.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/cql3/statements/CreateViewStatement.java b/src/java/org/apache/cassandra/cql3/statements/CreateViewStatement.java
index 778a3f4..cce954f 100644
--- a/src/java/org/apache/cassandra/cql3/statements/CreateViewStatement.java
+++ b/src/java/org/apache/cassandra/cql3/statements/CreateViewStatement.java
@@ -214,7 +214,7 @@ public class CreateViewStatement extends SchemaAlteringStatement
rawSelect.prepareKeyspace(state);
rawSelect.setBoundVariables(getBoundVariables());
- ParsedStatement.Prepared prepared = rawSelect.prepare(true);
+ ParsedStatement.Prepared prepared = rawSelect.prepare(true, queryState.getClientState());
SelectStatement select = (SelectStatement) prepared.statement;
StatementRestrictions restrictions = select.getRestrictions();
http://git-wip-us.apache.org/repos/asf/cassandra/blob/6c29ee84/src/java/org/apache/cassandra/cql3/statements/DropFunctionStatement.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/cql3/statements/DropFunctionStatement.java b/src/java/org/apache/cassandra/cql3/statements/DropFunctionStatement.java
index 138691e..8845a82 100644
--- a/src/java/org/apache/cassandra/cql3/statements/DropFunctionStatement.java
+++ b/src/java/org/apache/cassandra/cql3/statements/DropFunctionStatement.java
@@ -63,7 +63,7 @@ public final class DropFunctionStatement extends SchemaAlteringStatement
}
@Override
- public Prepared prepare() throws InvalidRequestException
+ public Prepared prepare(ClientState clientState) throws InvalidRequestException
{
if (Schema.instance.getKSMetaData(functionName.keyspace) != null)
{
@@ -82,7 +82,7 @@ public final class DropFunctionStatement extends SchemaAlteringStatement
}
}
- return super.prepare();
+ return super.prepare(clientState);
}
@Override
http://git-wip-us.apache.org/repos/asf/cassandra/blob/6c29ee84/src/java/org/apache/cassandra/cql3/statements/ModificationStatement.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/cql3/statements/ModificationStatement.java b/src/java/org/apache/cassandra/cql3/statements/ModificationStatement.java
index 28fc90f..8ae4d64 100644
--- a/src/java/org/apache/cassandra/cql3/statements/ModificationStatement.java
+++ b/src/java/org/apache/cassandra/cql3/statements/ModificationStatement.java
@@ -793,17 +793,16 @@ public abstract class ModificationStatement implements CQLStatement
this.ifExists = ifExists;
}
- public ParsedStatement.Prepared prepare()
+ public ParsedStatement.Prepared prepare(ClientState clientState)
{
VariableSpecifications boundNames = getBoundVariables();
- ModificationStatement statement = prepare(boundNames);
- CFMetaData cfm = ThriftValidation.validateColumnFamily(keyspace(), columnFamily());
- return new ParsedStatement.Prepared(statement, boundNames, boundNames.getPartitionKeyBindIndexes(cfm));
+ ModificationStatement statement = prepare(boundNames, clientState);
+ return new ParsedStatement.Prepared(statement, boundNames, boundNames.getPartitionKeyBindIndexes(statement.cfm));
}
- public ModificationStatement prepare(VariableSpecifications boundNames)
+ public ModificationStatement prepare(VariableSpecifications boundNames, ClientState clientState)
{
- CFMetaData metadata = ThriftValidation.validateColumnFamily(keyspace(), columnFamily());
+ CFMetaData metadata = ThriftValidation.validateColumnFamilyWithCompactMode(keyspace(), columnFamily(), clientState.isNoCompactMode());
Attributes preparedAttributes = attrs.prepare(keyspace(), columnFamily());
preparedAttributes.collectMarkerSpecification(boundNames);
http://git-wip-us.apache.org/repos/asf/cassandra/blob/6c29ee84/src/java/org/apache/cassandra/cql3/statements/ParsedStatement.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/cql3/statements/ParsedStatement.java b/src/java/org/apache/cassandra/cql3/statements/ParsedStatement.java
index 4c3f8a9..01a1b5e 100644
--- a/src/java/org/apache/cassandra/cql3/statements/ParsedStatement.java
+++ b/src/java/org/apache/cassandra/cql3/statements/ParsedStatement.java
@@ -23,6 +23,7 @@ import java.util.List;
import org.apache.cassandra.cql3.*;
import org.apache.cassandra.cql3.functions.Function;
import org.apache.cassandra.exceptions.RequestValidationException;
+import org.apache.cassandra.service.ClientState;
public abstract class ParsedStatement
{
@@ -44,7 +45,7 @@ public abstract class ParsedStatement
this.variables = variables;
}
- public abstract Prepared prepare() throws RequestValidationException;
+ public abstract Prepared prepare(ClientState clientState) throws RequestValidationException;
public static class Prepared
{
http://git-wip-us.apache.org/repos/asf/cassandra/blob/6c29ee84/src/java/org/apache/cassandra/cql3/statements/SchemaAlteringStatement.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/cql3/statements/SchemaAlteringStatement.java b/src/java/org/apache/cassandra/cql3/statements/SchemaAlteringStatement.java
index 62ba0ae..e7ecb14 100644
--- a/src/java/org/apache/cassandra/cql3/statements/SchemaAlteringStatement.java
+++ b/src/java/org/apache/cassandra/cql3/statements/SchemaAlteringStatement.java
@@ -18,6 +18,8 @@
package org.apache.cassandra.cql3.statements;
import org.apache.cassandra.auth.AuthenticatedUser;
+import org.apache.cassandra.config.CFMetaData;
+import org.apache.cassandra.config.Schema;
import org.apache.cassandra.cql3.CFName;
import org.apache.cassandra.cql3.CQLStatement;
import org.apache.cassandra.cql3.QueryOptions;
@@ -25,9 +27,12 @@ import org.apache.cassandra.exceptions.InvalidRequestException;
import org.apache.cassandra.exceptions.RequestValidationException;
import org.apache.cassandra.service.ClientState;
import org.apache.cassandra.service.QueryState;
+import org.apache.cassandra.thrift.ThriftValidation;
import org.apache.cassandra.transport.Event;
import org.apache.cassandra.transport.messages.ResultMessage;
+import static org.apache.cassandra.cql3.statements.RequestValidations.invalidRequest;
+
/**
* Abstract class for statements that alter the schema.
*/
@@ -60,8 +65,33 @@ public abstract class SchemaAlteringStatement extends CFStatement implements CQL
}
@Override
- public Prepared prepare()
+ public Prepared prepare(ClientState clientState)
{
+ // We don't allow schema changes in no-compact mode on compact tables because it feels like unnecessary
+ // complication: applying the change on the non compact version of the table might be unsafe (the table is
+ // still compact in general), and applying it to the compact version in a no-compact connection feels
+ // confusing/unintuitive. If user want to alter the compact version, they can simply do so in a normal
+ // connection; if they want to alter the non-compact version, they should finish their transition and properly
+ // DROP COMPACT STORAGE on the table before doing so.
+ if (isColumnFamilyLevel && clientState.isNoCompactMode())
+ {
+ CFMetaData table = ThriftValidation.validateColumnFamily(keyspace(), columnFamily());
+ if (table.isCompactTable())
+ {
+ throw invalidRequest("Cannot alter schema of compact table %s.%s from a connection in NO-COMPACT mode",
+ table.ksName, table.cfName);
+ }
+ else if (table.isView())
+ {
+ CFMetaData baseTable = Schema.instance.getView(table.ksName, table.cfName).baseTableMetadata();
+ if (baseTable.isCompactTable())
+ throw new InvalidRequestException(String.format("Cannot ALTER schema of view %s.%s on compact table %s from "
+ + "a connection in NO-COMPACT mode",
+ table.ksName, table.cfName,
+ baseTable.ksName, baseTable.cfName));
+ }
+ }
+
return new Prepared(this);
}
http://git-wip-us.apache.org/repos/asf/cassandra/blob/6c29ee84/src/java/org/apache/cassandra/cql3/statements/SelectStatement.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/cql3/statements/SelectStatement.java b/src/java/org/apache/cassandra/cql3/statements/SelectStatement.java
index 2e090fa..1e867bc 100644
--- a/src/java/org/apache/cassandra/cql3/statements/SelectStatement.java
+++ b/src/java/org/apache/cassandra/cql3/statements/SelectStatement.java
@@ -887,14 +887,14 @@ public class SelectStatement implements CQLStatement
this.limit = limit;
}
- public ParsedStatement.Prepared prepare() throws InvalidRequestException
+ public ParsedStatement.Prepared prepare(ClientState clientState) throws InvalidRequestException
{
- return prepare(false);
+ return prepare(false, clientState);
}
- public ParsedStatement.Prepared prepare(boolean forView) throws InvalidRequestException
+ public ParsedStatement.Prepared prepare(boolean forView, ClientState clientState) throws InvalidRequestException
{
- CFMetaData cfm = ThriftValidation.validateColumnFamily(keyspace(), columnFamily());
+ CFMetaData cfm = ThriftValidation.validateColumnFamilyWithCompactMode(keyspace(), columnFamily(), clientState.isNoCompactMode());
VariableSpecifications boundNames = getBoundVariables();
Selection selection = selectClause.isEmpty()
http://git-wip-us.apache.org/repos/asf/cassandra/blob/6c29ee84/src/java/org/apache/cassandra/cql3/statements/TruncateStatement.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/cql3/statements/TruncateStatement.java b/src/java/org/apache/cassandra/cql3/statements/TruncateStatement.java
index 66b3da0..b697910 100644
--- a/src/java/org/apache/cassandra/cql3/statements/TruncateStatement.java
+++ b/src/java/org/apache/cassandra/cql3/statements/TruncateStatement.java
@@ -45,7 +45,7 @@ public class TruncateStatement extends CFStatement implements CQLStatement
return 0;
}
- public Prepared prepare() throws InvalidRequestException
+ public Prepared prepare(ClientState clientState) throws InvalidRequestException
{
return new Prepared(this);
}
http://git-wip-us.apache.org/repos/asf/cassandra/blob/6c29ee84/src/java/org/apache/cassandra/cql3/statements/UseStatement.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/cql3/statements/UseStatement.java b/src/java/org/apache/cassandra/cql3/statements/UseStatement.java
index fe3d518..e4685cc 100644
--- a/src/java/org/apache/cassandra/cql3/statements/UseStatement.java
+++ b/src/java/org/apache/cassandra/cql3/statements/UseStatement.java
@@ -39,7 +39,7 @@ public class UseStatement extends ParsedStatement implements CQLStatement
return 0;
}
- public Prepared prepare() throws InvalidRequestException
+ public Prepared prepare(ClientState clientState) throws InvalidRequestException
{
return new Prepared(this);
}
http://git-wip-us.apache.org/repos/asf/cassandra/blob/6c29ee84/src/java/org/apache/cassandra/db/view/View.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/db/view/View.java b/src/java/org/apache/cassandra/db/view/View.java
index 58e2a84..9716dc4 100644
--- a/src/java/org/apache/cassandra/db/view/View.java
+++ b/src/java/org/apache/cassandra/db/view/View.java
@@ -17,32 +17,38 @@
*/
package org.apache.cassandra.db.view;
-import java.nio.ByteBuffer;
-import java.util.*;
-import java.util.concurrent.TimeUnit;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.List;
+import java.util.UUID;
import java.util.stream.Collectors;
-
import javax.annotation.Nullable;
import com.google.common.collect.Iterables;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
-import org.apache.cassandra.cql3.*;
+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;
+import org.apache.cassandra.cql3.SingleColumnRelation;
+import org.apache.cassandra.cql3.Term;
import org.apache.cassandra.cql3.statements.ParsedStatement;
import org.apache.cassandra.cql3.statements.SelectStatement;
-import org.apache.cassandra.db.*;
-import org.apache.cassandra.config.*;
-import org.apache.cassandra.cql3.ColumnIdentifier;
+import org.apache.cassandra.db.ColumnFamilyStore;
+import org.apache.cassandra.db.DecoratedKey;
+import org.apache.cassandra.db.ReadQuery;
import org.apache.cassandra.db.compaction.CompactionManager;
-import org.apache.cassandra.db.partitions.*;
-import org.apache.cassandra.db.rows.*;
+import org.apache.cassandra.db.rows.Row;
import org.apache.cassandra.schema.KeyspaceMetadata;
import org.apache.cassandra.service.ClientState;
-import org.apache.cassandra.service.pager.QueryPager;
-import org.apache.cassandra.transport.Server;
import org.apache.cassandra.utils.FBUtilities;
-import org.apache.cassandra.utils.btree.BTreeSet;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
/**
* A View copies data from a base table into a view table which can be queried independently from the
@@ -176,7 +182,7 @@ public class View
ClientState state = ClientState.forInternalCalls();
state.setKeyspace(baseCfs.keyspace.getName());
rawSelect.prepareKeyspace(state);
- ParsedStatement.Prepared prepared = rawSelect.prepare(true);
+ ParsedStatement.Prepared prepared = rawSelect.prepare(true, ClientState.forInternalCalls());
select = (SelectStatement) prepared.statement;
}
http://git-wip-us.apache.org/repos/asf/cassandra/blob/6c29ee84/src/java/org/apache/cassandra/index/internal/keys/KeysSearcher.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/index/internal/keys/KeysSearcher.java b/src/java/org/apache/cassandra/index/internal/keys/KeysSearcher.java
index c14c5a7..7cf4c51 100644
--- a/src/java/org/apache/cassandra/index/internal/keys/KeysSearcher.java
+++ b/src/java/org/apache/cassandra/index/internal/keys/KeysSearcher.java
@@ -197,7 +197,13 @@ public class KeysSearcher extends CassandraIndexSearcher
}
else
{
- assert iterator.metadata().isCompactTable();
+ if (!iterator.metadata().isCompactTable())
+ {
+ logger.warn("Non-composite index was used on the table '{}' during the query. Starting from Cassandra 4.0, only " +
+ "composite indexes will be supported. If compact flags were dropped for this table, drop and re-create " +
+ "the index.", iterator.metadata().cfName);
+ }
+
Row data = iterator.staticRow();
if (index.isStale(data, indexedValue, nowInSec))
{
http://git-wip-us.apache.org/repos/asf/cassandra/blob/6c29ee84/src/java/org/apache/cassandra/repair/RepairRunnable.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/repair/RepairRunnable.java b/src/java/org/apache/cassandra/repair/RepairRunnable.java
index 213e5c5..77726d4 100644
--- a/src/java/org/apache/cassandra/repair/RepairRunnable.java
+++ b/src/java/org/apache/cassandra/repair/RepairRunnable.java
@@ -45,6 +45,7 @@ import org.apache.cassandra.dht.Range;
import org.apache.cassandra.dht.Token;
import org.apache.cassandra.repair.messages.RepairOption;
import org.apache.cassandra.service.ActiveRepairService;
+import org.apache.cassandra.service.ClientState;
import org.apache.cassandra.service.QueryState;
import org.apache.cassandra.service.StorageService;
import org.apache.cassandra.tracing.TraceKeyspace;
@@ -385,7 +386,7 @@ public class RepairRunnable extends WrappedRunnable implements ProgressEventNoti
String format = "select event_id, source, activity from %s.%s where session_id = ? and event_id > ? and event_id < ?;";
String query = String.format(format, TraceKeyspace.NAME, TraceKeyspace.EVENTS);
- SelectStatement statement = (SelectStatement) QueryProcessor.parseStatement(query).prepare().statement;
+ SelectStatement statement = (SelectStatement) QueryProcessor.parseStatement(query).prepare(ClientState.forInternalCalls()).statement;
ByteBuffer sessionIdBytes = ByteBufferUtil.bytes(sessionId);
InetAddress source = FBUtilities.getBroadcastAddress();
http://git-wip-us.apache.org/repos/asf/cassandra/blob/6c29ee84/src/java/org/apache/cassandra/service/ClientState.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/service/ClientState.java b/src/java/org/apache/cassandra/service/ClientState.java
index 32849bc..641d174 100644
--- a/src/java/org/apache/cassandra/service/ClientState.java
+++ b/src/java/org/apache/cassandra/service/ClientState.java
@@ -81,6 +81,12 @@ public class ClientState
private volatile AuthenticatedUser user;
private volatile String keyspace;
+ /**
+ * Force Compact Tables to be represented as CQL ones for the current client session (simulates
+ * ALTER .. DROP COMPACT STORAGE but only for this session)
+ */
+ private volatile boolean noCompactMode;
+
private static final QueryHandler cqlQueryHandler;
static
{
@@ -253,6 +259,16 @@ public class ClientState
keyspace = ks;
}
+ public void setNoCompactMode()
+ {
+ this.noCompactMode = true;
+ }
+
+ public boolean isNoCompactMode()
+ {
+ return noCompactMode;
+ }
+
/**
* Attempts to login the given user.
*/
http://git-wip-us.apache.org/repos/asf/cassandra/blob/6c29ee84/src/java/org/apache/cassandra/thrift/ThriftValidation.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/thrift/ThriftValidation.java b/src/java/org/apache/cassandra/thrift/ThriftValidation.java
index 99aed05..6ad791d 100644
--- a/src/java/org/apache/cassandra/thrift/ThriftValidation.java
+++ b/src/java/org/apache/cassandra/thrift/ThriftValidation.java
@@ -105,6 +105,11 @@ public class ThriftValidation
// To be used when the operation should be authorized whether this is a counter CF or not
public static CFMetaData validateColumnFamily(String keyspaceName, String cfName) throws org.apache.cassandra.exceptions.InvalidRequestException
{
+ return validateColumnFamilyWithCompactMode(keyspaceName, cfName, false);
+ }
+
+ public static CFMetaData validateColumnFamilyWithCompactMode(String keyspaceName, String cfName, boolean noCompactMode) throws org.apache.cassandra.exceptions.InvalidRequestException
+ {
validateKeyspace(keyspaceName);
if (cfName.isEmpty())
throw new org.apache.cassandra.exceptions.InvalidRequestException("non-empty table is required");
@@ -113,7 +118,10 @@ public class ThriftValidation
if (metadata == null)
throw new org.apache.cassandra.exceptions.InvalidRequestException("unconfigured table " + cfName);
- return metadata;
+ if (metadata.isCompactTable() && noCompactMode)
+ return metadata.asNonCompact();
+ else
+ return metadata;
}
/**
http://git-wip-us.apache.org/repos/asf/cassandra/blob/6c29ee84/src/java/org/apache/cassandra/transport/messages/StartupMessage.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/transport/messages/StartupMessage.java b/src/java/org/apache/cassandra/transport/messages/StartupMessage.java
index 04d8e62..774be6a 100644
--- a/src/java/org/apache/cassandra/transport/messages/StartupMessage.java
+++ b/src/java/org/apache/cassandra/transport/messages/StartupMessage.java
@@ -35,6 +35,7 @@ public class StartupMessage extends Message.Request
{
public static final String CQL_VERSION = "CQL_VERSION";
public static final String COMPRESSION = "COMPRESSION";
+ public static final String NO_COMPACT = "NO_COMPACT";
public static final Message.Codec<StartupMessage> codec = new Message.Codec<StartupMessage>()
{
@@ -97,6 +98,9 @@ public class StartupMessage extends Message.Request
}
}
+ if (options.containsKey(NO_COMPACT) && Boolean.parseBoolean(options.get(NO_COMPACT)))
+ state.getClientState().setNoCompactMode();
+
if (DatabaseDescriptor.getAuthenticator().requireAuthentication())
return new AuthenticateMessage(DatabaseDescriptor.getAuthenticator().getClass().getName());
else
http://git-wip-us.apache.org/repos/asf/cassandra/blob/6c29ee84/test/unit/org/apache/cassandra/cql3/ViewTest.java
----------------------------------------------------------------------
diff --git a/test/unit/org/apache/cassandra/cql3/ViewTest.java b/test/unit/org/apache/cassandra/cql3/ViewTest.java
index 4a4fe1a..136ae1c 100644
--- a/test/unit/org/apache/cassandra/cql3/ViewTest.java
+++ b/test/unit/org/apache/cassandra/cql3/ViewTest.java
@@ -48,6 +48,8 @@ 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.exceptions.SyntaxException;
import org.apache.cassandra.schema.KeyspaceParams;
import org.apache.cassandra.utils.FBUtilities;
@@ -1237,7 +1239,6 @@ public class ViewTest extends CQLTester
catch (Exception e)
{
}
-
}
@Test
@@ -1376,4 +1377,16 @@ public class ViewTest extends CQLTester
assertRows(execute("SELECT k, toJson(listval) from mv"),
row(0, "[[\"a\", \"1\"], [\"b\", \"2\"], [\"c\", \"3\"]]"));
}
+
+ @Test(expected = SyntaxException.class)
+ public void emptyViewNameTest() throws Throwable
+ {
+ execute("CREATE MATERIALIZED VIEW \"\" AS SELECT a, b FROM tbl WHERE b IS NOT NULL PRIMARY KEY (b, a)");
+ }
+
+ @Test(expected = SyntaxException.class)
+ public void emptyBaseTableNameTest() throws Throwable
+ {
+ execute("CREATE MATERIALIZED VIEW myview AS SELECT a, b FROM \"\" WHERE b IS NOT NULL PRIMARY KEY (b, a)");
+ }
}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/cassandra/blob/6c29ee84/test/unit/org/apache/cassandra/cql3/validation/entities/UFTest.java
----------------------------------------------------------------------
diff --git a/test/unit/org/apache/cassandra/cql3/validation/entities/UFTest.java b/test/unit/org/apache/cassandra/cql3/validation/entities/UFTest.java
index 8a743ea..6e6af19 100644
--- a/test/unit/org/apache/cassandra/cql3/validation/entities/UFTest.java
+++ b/test/unit/org/apache/cassandra/cql3/validation/entities/UFTest.java
@@ -34,6 +34,7 @@ import org.apache.cassandra.cql3.functions.FunctionName;
import org.apache.cassandra.cql3.functions.UDFunction;
import org.apache.cassandra.db.marshal.CollectionType;
import org.apache.cassandra.exceptions.InvalidRequestException;
+import org.apache.cassandra.exceptions.SyntaxException;
import org.apache.cassandra.schema.KeyspaceMetadata;
import org.apache.cassandra.service.ClientState;
import org.apache.cassandra.transport.Event;
@@ -968,4 +969,28 @@ public class UFTest extends CQLTester
assertRows(execute("SELECT " + fNameICC + "(empty_int) FROM %s"), row(0));
assertRows(execute("SELECT " + fNameICN + "(empty_int) FROM %s"), row(new Object[]{ null }));
}
+
+ @Test(expected = SyntaxException.class)
+ public void testEmptyFunctionName() throws Throwable
+ {
+ execute("CREATE FUNCTION IF NOT EXISTS " + KEYSPACE + ".\"\" (arg int)\n" +
+ " RETURNS NULL ON NULL INPUT\n" +
+ " RETURNS int\n" +
+ " LANGUAGE java\n" +
+ " AS $$\n" +
+ " return a;\n" +
+ " $$");
+ }
+
+ @Test(expected = SyntaxException.class)
+ public void testEmptyArgName() throws Throwable
+ {
+ execute("CREATE FUNCTION IF NOT EXISTS " + KEYSPACE + ".myfn (\"\" int)\n" +
+ " RETURNS NULL ON NULL INPUT\n" +
+ " RETURNS int\n" +
+ " LANGUAGE java\n" +
+ " AS $$\n" +
+ " return a;\n" +
+ " $$");
+ }
}
http://git-wip-us.apache.org/repos/asf/cassandra/blob/6c29ee84/test/unit/org/apache/cassandra/cql3/validation/entities/UserTypesTest.java
----------------------------------------------------------------------
diff --git a/test/unit/org/apache/cassandra/cql3/validation/entities/UserTypesTest.java b/test/unit/org/apache/cassandra/cql3/validation/entities/UserTypesTest.java
index dfc2e5e..68c0b8c 100644
--- a/test/unit/org/apache/cassandra/cql3/validation/entities/UserTypesTest.java
+++ b/test/unit/org/apache/cassandra/cql3/validation/entities/UserTypesTest.java
@@ -24,6 +24,7 @@ import org.junit.Test;
import org.apache.cassandra.cql3.CQLTester;
import org.apache.cassandra.dht.ByteOrderedPartitioner;
+import org.apache.cassandra.exceptions.*;
import org.apache.cassandra.service.StorageService;
public class UserTypesTest extends CQLTester
@@ -713,6 +714,25 @@ public class UserTypesTest extends CQLTester
row(1, 1,set(userType(1), userType(1, 1), userType(1, 2), userType(2), userType(2, 1)), 2));
}
+ @Test(expected = SyntaxException.class)
+ public void emptyTypeNameTest() throws Throwable
+ {
+ execute("CREATE TYPE \"\" (a int, b int)");
+ }
+
+ @Test(expected = SyntaxException.class)
+ public void emptyFieldNameTest() throws Throwable
+ {
+ execute("CREATE TYPE mytype (\"\" int, b int)");
+ }
+
+ @Test(expected = SyntaxException.class)
+ public void renameColumnToEmpty() throws Throwable
+ {
+ String typeName = createType("CREATE TYPE %s (a int, b int)");
+ execute(String.format("ALTER TYPE %s.%s RENAME b TO \"\"", keyspace(), typeName));
+ }
+
private String typeWithKs(String type1)
{
return keyspace() + '.' + type1;
http://git-wip-us.apache.org/repos/asf/cassandra/blob/6c29ee84/test/unit/org/apache/cassandra/cql3/validation/operations/AlterTest.java
----------------------------------------------------------------------
diff --git a/test/unit/org/apache/cassandra/cql3/validation/operations/AlterTest.java b/test/unit/org/apache/cassandra/cql3/validation/operations/AlterTest.java
index c48ffe5..b37462f 100644
--- a/test/unit/org/apache/cassandra/cql3/validation/operations/AlterTest.java
+++ b/test/unit/org/apache/cassandra/cql3/validation/operations/AlterTest.java
@@ -17,6 +17,9 @@
*/
package org.apache.cassandra.cql3.validation.operations;
+import org.junit.Assert;
+import org.junit.Test;
+
import org.apache.cassandra.cql3.CQLTester;
import org.apache.cassandra.db.ColumnFamilyStore;
import org.apache.cassandra.db.Keyspace;
@@ -24,11 +27,6 @@ import org.apache.cassandra.exceptions.ConfigurationException;
import org.apache.cassandra.exceptions.InvalidRequestException;
import org.apache.cassandra.exceptions.SyntaxException;
import org.apache.cassandra.schema.SchemaKeyspace;
-import org.apache.cassandra.transport.Server;
-import org.apache.cassandra.utils.ByteBufferUtil;
-
-import org.junit.Assert;
-import org.junit.Test;
import static java.lang.String.format;
import static org.junit.Assert.assertEquals;
@@ -266,6 +264,13 @@ public class AlterTest extends CQLTester
execute("alter table %s add v int");
}
+ @Test(expected = SyntaxException.class)
+ public void renameToEmptyTest() throws Throwable
+ {
+ createTable("CREATE TABLE %s (k int, c1 int, v int, PRIMARY KEY (k, c1))");
+ execute("ALTER TABLE %s RENAME c1 TO \"\"");
+ }
+
@Test
// tests CASSANDRA-9565
public void testDoubleWith() throws Throwable
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@cassandra.apache.org
For additional commands, e-mail: commits-help@cassandra.apache.org