You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cassandra.apache.org by sl...@apache.org on 2015/11/26 10:23:09 UTC
[3/3] cassandra git commit: Fix JSON update with prepared statements
(patch for 3.0)
Fix JSON update with prepared statements (patch for 3.0)
patch by slebresne; reviewed by thobbs for CASSANDRA-10631
Project: http://git-wip-us.apache.org/repos/asf/cassandra/repo
Commit: http://git-wip-us.apache.org/repos/asf/cassandra/commit/2cbd7762
Tree: http://git-wip-us.apache.org/repos/asf/cassandra/tree/2cbd7762
Diff: http://git-wip-us.apache.org/repos/asf/cassandra/diff/2cbd7762
Branch: refs/heads/cassandra-3.0
Commit: 2cbd776250553a4e5d3dbb4dc286a3ceb7724158
Parents: b5fef75
Author: Sylvain Lebresne <sy...@datastax.com>
Authored: Mon Nov 2 13:18:59 2015 +0100
Committer: Sylvain Lebresne <sy...@datastax.com>
Committed: Thu Nov 26 10:22:53 2015 +0100
----------------------------------------------------------------------
CHANGES.txt | 1 +
src/java/org/apache/cassandra/cql3/Json.java | 25 +---------
.../org/apache/cassandra/cql3/QueryOptions.java | 52 ++++++++++++++++++--
.../apache/cassandra/cql3/QueryProcessor.java | 40 ++++++++++++---
.../cql3/statements/AlterKeyspaceStatement.java | 7 +--
.../cql3/statements/AlterTableStatement.java | 9 +---
.../cql3/statements/AlterTypeStatement.java | 9 +---
.../cql3/statements/AlterViewStatement.java | 9 +---
.../statements/CreateAggregateStatement.java | 27 +++-------
.../statements/CreateFunctionStatement.java | 23 +++------
.../cql3/statements/CreateIndexStatement.java | 8 +--
.../statements/CreateKeyspaceStatement.java | 11 ++---
.../cql3/statements/CreateTableStatement.java | 11 ++---
.../cql3/statements/CreateTriggerStatement.java | 9 +---
.../cql3/statements/CreateTypeStatement.java | 11 ++---
.../cql3/statements/CreateViewStatement.java | 12 ++---
.../cql3/statements/DropAggregateStatement.java | 19 ++-----
.../cql3/statements/DropFunctionStatement.java | 20 ++------
.../cql3/statements/DropIndexStatement.java | 41 +++++++--------
.../cql3/statements/DropKeyspaceStatement.java | 11 ++---
.../cql3/statements/DropTableStatement.java | 11 ++---
.../cql3/statements/DropTriggerStatement.java | 9 +---
.../cql3/statements/DropTypeStatement.java | 11 ++---
.../cql3/statements/DropViewStatement.java | 11 ++---
.../statements/SchemaAlteringStatement.java | 26 ++++------
.../org/apache/cassandra/cql3/CQLTester.java | 29 ++++++++++-
.../validation/entities/SecondaryIndexTest.java | 9 ++++
.../index/internal/CassandraIndexTest.java | 8 +++
28 files changed, 220 insertions(+), 249 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/cassandra/blob/2cbd7762/CHANGES.txt
----------------------------------------------------------------------
diff --git a/CHANGES.txt b/CHANGES.txt
index db6c72f..bd7006e 100644
--- a/CHANGES.txt
+++ b/CHANGES.txt
@@ -9,6 +9,7 @@
* Keep the file open in trySkipCache (CASSANDRA-10669)
* Updated trigger example (CASSANDRA-10257)
Merged from 2.2:
+ * Fix JSON update with prepared statements (CASSANDRA-10631)
* Don't do anticompaction after subrange repair (CASSANDRA-10422)
* Fix SimpleDateType type compatibility (CASSANDRA-10027)
* (Hadoop) fix splits calculation (CASSANDRA-10640)
http://git-wip-us.apache.org/repos/asf/cassandra/blob/2cbd7762/src/java/org/apache/cassandra/cql3/Json.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/cql3/Json.java b/src/java/org/apache/cassandra/cql3/Json.java
index df2d9ab..26e7ff2 100644
--- a/src/java/org/apache/cassandra/cql3/Json.java
+++ b/src/java/org/apache/cassandra/cql3/Json.java
@@ -135,8 +135,6 @@ public class Json
private final int bindIndex;
private final Collection<ColumnDefinition> columns;
- private Map<ColumnIdentifier, Term> columnMap;
-
public PreparedMarker(int bindIndex, Collection<ColumnDefinition> columns)
{
this.bindIndex = bindIndex;
@@ -147,24 +145,6 @@ public class Json
{
return new RawDelayedColumnValue(this, def);
}
-
- public void bind(QueryOptions options) throws InvalidRequestException
- {
- // this will be called once per column, so avoid duplicating work
- if (columnMap != null)
- return;
-
- ByteBuffer value = options.getValues().get(bindIndex);
- if (value == null)
- throw new InvalidRequestException("Got null for INSERT JSON values");
-
- columnMap = parseJson(UTF8Type.instance.getSerializer().deserialize(value), columns);
- }
-
- public Term getValue(ColumnDefinition def)
- {
- return columnMap.get(def.name);
- }
}
/**
@@ -261,8 +241,7 @@ public class Json
@Override
public Terminal bind(QueryOptions options) throws InvalidRequestException
{
- marker.bind(options);
- Term term = marker.getValue(column);
+ Term term = options.getJsonColumnValue(marker.bindIndex, column.name, marker.columns);
return term == null ? null : term.bind(options);
}
@@ -277,7 +256,7 @@ public class Json
/**
* Given a JSON string, return a map of columns to their values for the insert.
*/
- private static Map<ColumnIdentifier, Term> parseJson(String jsonString, Collection<ColumnDefinition> expectedReceivers)
+ public static Map<ColumnIdentifier, Term> parseJson(String jsonString, Collection<ColumnDefinition> expectedReceivers)
{
try
{
http://git-wip-us.apache.org/repos/asf/cassandra/blob/2cbd7762/src/java/org/apache/cassandra/cql3/QueryOptions.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/cql3/QueryOptions.java b/src/java/org/apache/cassandra/cql3/QueryOptions.java
index e6e80e3..6324911 100644
--- a/src/java/org/apache/cassandra/cql3/QueryOptions.java
+++ b/src/java/org/apache/cassandra/cql3/QueryOptions.java
@@ -18,15 +18,15 @@
package org.apache.cassandra.cql3;
import java.nio.ByteBuffer;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.EnumSet;
-import java.util.List;
+import java.util.*;
import com.google.common.collect.ImmutableList;
-
import io.netty.buffer.ByteBuf;
+
+import org.apache.cassandra.config.ColumnDefinition;
import org.apache.cassandra.db.ConsistencyLevel;
+import org.apache.cassandra.db.marshal.UTF8Type;
+import org.apache.cassandra.exceptions.InvalidRequestException;
import org.apache.cassandra.service.QueryState;
import org.apache.cassandra.service.pager.PagingState;
import org.apache.cassandra.transport.CBCodec;
@@ -48,6 +48,9 @@ public abstract class QueryOptions
public static final CBCodec<QueryOptions> codec = new Codec();
+ // A cache of bind values parsed as JSON, see getJsonColumnValue for details.
+ private List<Map<ColumnIdentifier, Term>> jsonValuesCache;
+
public static QueryOptions fromThrift(ConsistencyLevel consistency, List<ByteBuffer> values)
{
return new DefaultQueryOptions(consistency, values, false, SpecificOptions.DEFAULT, Server.VERSION_3);
@@ -83,6 +86,45 @@ public abstract class QueryOptions
public abstract boolean skipMetadata();
/**
+ * Returns the term corresponding to column {@code columnName} in the JSON value of bind index {@code bindIndex}.
+ *
+ * This is functionally equivalent to:
+ * {@code Json.parseJson(UTF8Type.instance.getSerializer().deserialize(getValues().get(bindIndex)), expectedReceivers).get(columnName)}
+ * but this cache the result of parsing the JSON so that while this might be called for multiple columns on the same {@code bindIndex}
+ * value, the underlying JSON value is only parsed/processed once.
+ *
+ * Note: this is a bit more involved in CQL specifics than this class generally is but we as we need to cache this per-query and in an object
+ * that is available when we bind values, this is the easier place to have this.
+ *
+ * @param bindIndex the index of the bind value that should be interpreted as a JSON value.
+ * @param columnName the name of the column we want the value of.
+ * @param expectedReceivers the columns expected in the JSON value at index {@code bindIndex}. This is only used when parsing the
+ * json initially and no check is done afterwards. So in practice, any call of this method on the same QueryOptions object and with the same
+ * {@code bindIndx} values should use the same value for this parameter, but this isn't validated in any way.
+ *
+ * @return the value correspong to column {@code columnName} in the (JSON) bind value at index {@code bindIndex}. This may return null if the
+ * JSON value has no value for this column.
+ */
+ public Term getJsonColumnValue(int bindIndex, ColumnIdentifier columnName, Collection<ColumnDefinition> expectedReceivers) throws InvalidRequestException
+ {
+ if (jsonValuesCache == null)
+ jsonValuesCache = new ArrayList<>(Collections.<Map<ColumnIdentifier, Term>>nCopies(getValues().size(), null));
+
+ Map<ColumnIdentifier, Term> jsonValue = jsonValuesCache.get(bindIndex);
+ if (jsonValue == null)
+ {
+ ByteBuffer value = getValues().get(bindIndex);
+ if (value == null)
+ throw new InvalidRequestException("Got null for INSERT JSON values");
+
+ jsonValue = Json.parseJson(UTF8Type.instance.getSerializer().deserialize(value), expectedReceivers);
+ jsonValuesCache.set(bindIndex, jsonValue);
+ }
+
+ return jsonValue.get(columnName);
+ }
+
+ /**
* Tells whether or not this <code>QueryOptions</code> contains the column specifications for the bound variables.
* <p>The column specifications will be present only for prepared statements.</p>
* @return <code>true</code> this <code>QueryOptions</code> contains the column specifications for the bound
http://git-wip-us.apache.org/repos/asf/cassandra/blob/2cbd7762/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 59d4148..96e8387 100644
--- a/src/java/org/apache/cassandra/cql3/QueryProcessor.java
+++ b/src/java/org/apache/cassandra/cql3/QueryProcessor.java
@@ -24,6 +24,7 @@ import java.util.concurrent.ConcurrentMap;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;
+import com.google.common.annotations.VisibleForTesting;
import com.google.common.base.Predicate;
import com.google.common.collect.Iterables;
import com.google.common.collect.Iterators;
@@ -533,6 +534,15 @@ public class QueryProcessor implements QueryHandler
return meter.measureDeep(key);
}
+ /**
+ * Clear our internal statmeent cache for test purposes.
+ */
+ @VisibleForTesting
+ public static void clearInternalStatementsCache()
+ {
+ internalStatements.clear();
+ }
+
private static class MigrationSubscriber extends MigrationListener
{
private void removeInvalidPreparedStatements(String ksName, String cfName)
@@ -601,10 +611,7 @@ public class QueryProcessor implements QueryHandler
// in case there are other overloads, we have to remove all overloads since argument type
// matching may change (due to type casting)
if (Schema.instance.getKSMetaData(ksName).functions.get(new FunctionName(ksName, functionName)).size() > 1)
- {
- removeInvalidPreparedStatementsForFunction(preparedStatements.values().iterator(), ksName, functionName);
- removeInvalidPreparedStatementsForFunction(thriftPreparedStatements.values().iterator(), ksName, functionName);
- }
+ removeAllInvalidPreparedStatementsForFunction(ksName, functionName);
}
public void onUpdateColumnFamily(String ksName, String cfName, boolean columnsDidChange)
@@ -614,6 +621,24 @@ public class QueryProcessor implements QueryHandler
removeInvalidPreparedStatements(ksName, cfName);
}
+ public void onUpdateFunction(String ksName, String functionName, List<AbstractType<?>> argTypes)
+ {
+ // Updating a function may imply we've changed the body of the function, so we need to invalid statements so that
+ // the new definition is picked (the function is resolved at preparation time).
+ // TODO: if the function has multiple overload, we could invalidate only the statement refering to the overload
+ // that was updated. This requires a few changes however and probably doesn't matter much in practice.
+ removeAllInvalidPreparedStatementsForFunction(ksName, functionName);
+ }
+
+ public void onUpdateAggregate(String ksName, String aggregateName, List<AbstractType<?>> argTypes)
+ {
+ // Updating a function may imply we've changed the body of the function, so we need to invalid statements so that
+ // the new definition is picked (the function is resolved at preparation time).
+ // TODO: if the function has multiple overload, we could invalidate only the statement refering to the overload
+ // that was updated. This requires a few changes however and probably doesn't matter much in practice.
+ removeAllInvalidPreparedStatementsForFunction(ksName, aggregateName);
+ }
+
public void onDropKeyspace(String ksName)
{
logger.trace("Keyspace {} was dropped, invalidating related prepared statements", ksName);
@@ -628,16 +653,17 @@ public class QueryProcessor implements QueryHandler
public void onDropFunction(String ksName, String functionName, List<AbstractType<?>> argTypes)
{
- onDropFunctionInternal(ksName, functionName, argTypes);
+ removeAllInvalidPreparedStatementsForFunction(ksName, functionName);
}
public void onDropAggregate(String ksName, String aggregateName, List<AbstractType<?>> argTypes)
{
- onDropFunctionInternal(ksName, aggregateName, argTypes);
+ removeAllInvalidPreparedStatementsForFunction(ksName, aggregateName);
}
- private static void onDropFunctionInternal(String ksName, String functionName, List<AbstractType<?>> argTypes)
+ private static void removeAllInvalidPreparedStatementsForFunction(String ksName, String functionName)
{
+ removeInvalidPreparedStatementsForFunction(internalStatements.values().iterator(), ksName, functionName);
removeInvalidPreparedStatementsForFunction(preparedStatements.values().iterator(), ksName, functionName);
removeInvalidPreparedStatementsForFunction(thriftPreparedStatements.values().iterator(), ksName, functionName);
}
http://git-wip-us.apache.org/repos/asf/cassandra/blob/2cbd7762/src/java/org/apache/cassandra/cql3/statements/AlterKeyspaceStatement.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/cql3/statements/AlterKeyspaceStatement.java b/src/java/org/apache/cassandra/cql3/statements/AlterKeyspaceStatement.java
index b660f52..5642b0d 100644
--- a/src/java/org/apache/cassandra/cql3/statements/AlterKeyspaceStatement.java
+++ b/src/java/org/apache/cassandra/cql3/statements/AlterKeyspaceStatement.java
@@ -75,7 +75,7 @@ public class AlterKeyspaceStatement extends SchemaAlteringStatement
}
}
- public boolean announceMigration(boolean isLocalOnly) throws RequestValidationException
+ public Event.SchemaChange announceMigration(boolean isLocalOnly) throws RequestValidationException
{
KeyspaceMetadata oldKsm = Schema.instance.getKSMetaData(name);
// In the (very) unlikely case the keyspace was dropped since validate()
@@ -84,11 +84,6 @@ public class AlterKeyspaceStatement extends SchemaAlteringStatement
KeyspaceMetadata newKsm = oldKsm.withSwapped(attrs.asAlteredKeyspaceParams(oldKsm.params));
MigrationManager.announceKeyspaceUpdate(newKsm, isLocalOnly);
- return true;
- }
-
- public Event.SchemaChange changeEvent()
- {
return new Event.SchemaChange(Event.SchemaChange.Change.UPDATED, keyspace());
}
}
http://git-wip-us.apache.org/repos/asf/cassandra/blob/2cbd7762/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 a9b9d37..3515c6b 100644
--- a/src/java/org/apache/cassandra/cql3/statements/AlterTableStatement.java
+++ b/src/java/org/apache/cassandra/cql3/statements/AlterTableStatement.java
@@ -85,7 +85,7 @@ public class AlterTableStatement extends SchemaAlteringStatement
// validated in announceMigration()
}
- public boolean announceMigration(boolean isLocalOnly) throws RequestValidationException
+ public Event.SchemaChange announceMigration(boolean isLocalOnly) throws RequestValidationException
{
CFMetaData meta = validateColumnFamily(keyspace(), columnFamily());
if (meta.isView())
@@ -329,7 +329,7 @@ public class AlterTableStatement extends SchemaAlteringStatement
for (ViewDefinition viewUpdate : viewUpdates)
MigrationManager.announceViewUpdate(viewUpdate, isLocalOnly);
}
- return true;
+ return new Event.SchemaChange(Event.SchemaChange.Change.UPDATED, Event.SchemaChange.Target.TABLE, keyspace(), columnFamily());
}
private static void validateAlter(CFMetaData cfm, ColumnDefinition def, AbstractType<?> validatorType)
@@ -387,9 +387,4 @@ public class AlterTableStatement extends SchemaAlteringStatement
rawColumnName,
validator);
}
-
- public Event.SchemaChange changeEvent()
- {
- return new Event.SchemaChange(Event.SchemaChange.Change.UPDATED, Event.SchemaChange.Target.TABLE, keyspace(), columnFamily());
- }
}
http://git-wip-us.apache.org/repos/asf/cassandra/blob/2cbd7762/src/java/org/apache/cassandra/cql3/statements/AlterTypeStatement.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/cql3/statements/AlterTypeStatement.java b/src/java/org/apache/cassandra/cql3/statements/AlterTypeStatement.java
index 24bf4cb..068b996 100644
--- a/src/java/org/apache/cassandra/cql3/statements/AlterTypeStatement.java
+++ b/src/java/org/apache/cassandra/cql3/statements/AlterTypeStatement.java
@@ -78,18 +78,13 @@ public abstract class AlterTypeStatement extends SchemaAlteringStatement
// It doesn't really change anything anyway.
}
- public Event.SchemaChange changeEvent()
- {
- return new Event.SchemaChange(Event.SchemaChange.Change.UPDATED, Event.SchemaChange.Target.TYPE, keyspace(), name.getStringTypeName());
- }
-
@Override
public String keyspace()
{
return name.getKeyspace();
}
- public boolean announceMigration(boolean isLocalOnly) throws InvalidRequestException, ConfigurationException
+ public Event.SchemaChange announceMigration(boolean isLocalOnly) throws InvalidRequestException, ConfigurationException
{
KeyspaceMetadata ksm = Schema.instance.getKSMetaData(name.getKeyspace());
if (ksm == null)
@@ -140,7 +135,7 @@ public abstract class AlterTypeStatement extends SchemaAlteringStatement
if (upd != null)
MigrationManager.announceTypeUpdate((UserType) upd, isLocalOnly);
}
- return true;
+ return new Event.SchemaChange(Event.SchemaChange.Change.UPDATED, Event.SchemaChange.Target.TYPE, keyspace(), name.getStringTypeName());
}
private static int getIdxOfField(UserType type, ColumnIdentifier field)
http://git-wip-us.apache.org/repos/asf/cassandra/blob/2cbd7762/src/java/org/apache/cassandra/cql3/statements/AlterViewStatement.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/cql3/statements/AlterViewStatement.java b/src/java/org/apache/cassandra/cql3/statements/AlterViewStatement.java
index e12ebd7..5b1699b 100644
--- a/src/java/org/apache/cassandra/cql3/statements/AlterViewStatement.java
+++ b/src/java/org/apache/cassandra/cql3/statements/AlterViewStatement.java
@@ -55,7 +55,7 @@ public class AlterViewStatement extends SchemaAlteringStatement
// validated in announceMigration()
}
- public boolean announceMigration(boolean isLocalOnly) throws RequestValidationException
+ public Event.SchemaChange announceMigration(boolean isLocalOnly) throws RequestValidationException
{
CFMetaData meta = validateColumnFamily(keyspace(), columnFamily());
if (!meta.isView())
@@ -78,16 +78,11 @@ public class AlterViewStatement extends SchemaAlteringStatement
viewCopy.metadata.params(params);
MigrationManager.announceViewUpdate(viewCopy, isLocalOnly);
- return true;
+ return new Event.SchemaChange(Event.SchemaChange.Change.UPDATED, Event.SchemaChange.Target.TABLE, keyspace(), columnFamily());
}
public String toString()
{
return String.format("AlterViewStatement(name=%s)", cfName);
}
-
- public Event.SchemaChange changeEvent()
- {
- return new Event.SchemaChange(Event.SchemaChange.Change.UPDATED, Event.SchemaChange.Target.TABLE, keyspace(), columnFamily());
- }
}
http://git-wip-us.apache.org/repos/asf/cassandra/blob/2cbd7762/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 6fd0334..50f4f12 100644
--- a/src/java/org/apache/cassandra/cql3/statements/CreateAggregateStatement.java
+++ b/src/java/org/apache/cassandra/cql3/statements/CreateAggregateStatement.java
@@ -50,9 +50,6 @@ public final class CreateAggregateStatement extends SchemaAlteringStatement
private final List<CQL3Type.Raw> argRawTypes;
private final Term.Raw ival;
- private UDAggregate udAggregate;
- private boolean replaced;
-
private List<AbstractType<?>> argTypes;
private AbstractType<?> returnType;
private ScalarFunction stateFunction;
@@ -192,20 +189,14 @@ public final class CreateAggregateStatement extends SchemaAlteringStatement
throw new InvalidRequestException(String.format("Cannot add aggregate '%s' to non existing keyspace '%s'.", functionName.name, functionName.keyspace));
}
- public Event.SchemaChange changeEvent()
- {
- return new Event.SchemaChange(replaced ? Event.SchemaChange.Change.UPDATED : Event.SchemaChange.Change.CREATED,
- Event.SchemaChange.Target.AGGREGATE,
- udAggregate.name().keyspace, udAggregate.name().name, AbstractType.asCQLTypeStringList(udAggregate.argTypes()));
- }
-
- public boolean announceMigration(boolean isLocalOnly) throws RequestValidationException
+ public Event.SchemaChange announceMigration(boolean isLocalOnly) throws RequestValidationException
{
Function old = Schema.instance.findFunction(functionName, argTypes).orElse(null);
- if (old != null)
+ boolean replaced = old != null;
+ if (replaced)
{
if (ifNotExists)
- return false;
+ return null;
if (!orReplace)
throw new InvalidRequestException(String.format("Function %s already exists", old));
if (!(old instanceof AggregateFunction))
@@ -223,15 +214,13 @@ public final class CreateAggregateStatement extends SchemaAlteringStatement
if (!stateFunction.isCalledOnNullInput() && initcond == null)
throw new InvalidRequestException(String.format("Cannot create aggregate %s without INITCOND because state function %s does not accept 'null' arguments", functionName, stateFunc));
- udAggregate = new UDAggregate(functionName, argTypes, returnType,
- stateFunction,
- finalFunction,
- initcond);
- replaced = old != null;
+ UDAggregate udAggregate = new UDAggregate(functionName, argTypes, returnType, stateFunction, finalFunction, initcond);
MigrationManager.announceNewAggregate(udAggregate, isLocalOnly);
- return true;
+ return new Event.SchemaChange(replaced ? Event.SchemaChange.Change.UPDATED : Event.SchemaChange.Change.CREATED,
+ Event.SchemaChange.Target.AGGREGATE,
+ udAggregate.name().keyspace, udAggregate.name().name, AbstractType.asCQLTypeStringList(udAggregate.argTypes()));
}
private static String stateFuncSig(FunctionName stateFuncName, CQL3Type.Raw stateTypeRaw, List<CQL3Type.Raw> argRawTypes)
http://git-wip-us.apache.org/repos/asf/cassandra/blob/2cbd7762/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 bd632bb..a54c49e 100644
--- a/src/java/org/apache/cassandra/cql3/statements/CreateFunctionStatement.java
+++ b/src/java/org/apache/cassandra/cql3/statements/CreateFunctionStatement.java
@@ -54,8 +54,6 @@ public final class CreateFunctionStatement extends SchemaAlteringStatement
private List<AbstractType<?>> argTypes;
private AbstractType<?> returnType;
- private UDFunction udFunction;
- private boolean replaced;
public CreateFunctionStatement(FunctionName functionName,
String language,
@@ -140,20 +138,14 @@ public final class CreateFunctionStatement extends SchemaAlteringStatement
throw new InvalidRequestException(String.format("Cannot add function '%s' to non existing keyspace '%s'.", functionName.name, functionName.keyspace));
}
- public Event.SchemaChange changeEvent()
- {
- return new Event.SchemaChange(replaced ? Event.SchemaChange.Change.UPDATED : Event.SchemaChange.Change.CREATED,
- Event.SchemaChange.Target.FUNCTION,
- udFunction.name().keyspace, udFunction.name().name, AbstractType.asCQLTypeStringList(udFunction.argTypes()));
- }
-
- public boolean announceMigration(boolean isLocalOnly) throws RequestValidationException
+ public Event.SchemaChange announceMigration(boolean isLocalOnly) throws RequestValidationException
{
Function old = Schema.instance.findFunction(functionName, argTypes).orElse(null);
- if (old != null)
+ boolean replaced = old != null;
+ if (replaced)
{
if (ifNotExists)
- return false;
+ return null;
if (!orReplace)
throw new InvalidRequestException(String.format("Function %s already exists", old));
if (!(old instanceof ScalarFunction))
@@ -167,12 +159,13 @@ public final class CreateFunctionStatement extends SchemaAlteringStatement
functionName, returnType.asCQL3Type(), old.returnType().asCQL3Type()));
}
- this.udFunction = UDFunction.create(functionName, argNames, argTypes, returnType, calledOnNullInput, language, body);
- this.replaced = old != null;
+ UDFunction udFunction = UDFunction.create(functionName, argNames, argTypes, returnType, calledOnNullInput, language, body);
MigrationManager.announceNewFunction(udFunction, isLocalOnly);
- return true;
+ return new Event.SchemaChange(replaced ? Event.SchemaChange.Change.UPDATED : Event.SchemaChange.Change.CREATED,
+ Event.SchemaChange.Target.FUNCTION,
+ udFunction.name().keyspace, udFunction.name().name, AbstractType.asCQLTypeStringList(udFunction.argTypes()));
}
private AbstractType<?> prepareType(String typeName, CQL3Type.Raw rawType)
http://git-wip-us.apache.org/repos/asf/cassandra/blob/2cbd7762/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 e26a1eb..b2a6fd5 100644
--- a/src/java/org/apache/cassandra/cql3/statements/CreateIndexStatement.java
+++ b/src/java/org/apache/cassandra/cql3/statements/CreateIndexStatement.java
@@ -188,7 +188,7 @@ public class CreateIndexStatement extends SchemaAlteringStatement
throw new InvalidRequestException("Duplicate column " + target.column + " in index target list");
}
- public boolean announceMigration(boolean isLocalOnly) throws RequestValidationException
+ public Event.SchemaChange announceMigration(boolean isLocalOnly) throws RequestValidationException
{
CFMetaData cfm = Schema.instance.getCFMetaData(keyspace(), columnFamily()).copy();
List<IndexTarget> targets = new ArrayList<>(rawTargets.size());
@@ -206,7 +206,7 @@ public class CreateIndexStatement extends SchemaAlteringStatement
if (Schema.instance.getKSMetaData(keyspace()).existingIndexNames(null).contains(acceptedName))
{
if (ifNotExists)
- return false;
+ return null;
else
throw new InvalidRequestException(String.format("Index %s already exists", acceptedName));
}
@@ -237,11 +237,7 @@ public class CreateIndexStatement extends SchemaAlteringStatement
cfm.indexes(cfm.getIndexes().with(index));
MigrationManager.announceColumnFamilyUpdate(cfm, false, isLocalOnly);
- return true;
- }
- public Event.SchemaChange changeEvent()
- {
// Creating an index is akin to updating the CF
return new Event.SchemaChange(Event.SchemaChange.Change.UPDATED, Event.SchemaChange.Target.TABLE, keyspace(), columnFamily());
}
http://git-wip-us.apache.org/repos/asf/cassandra/blob/2cbd7762/src/java/org/apache/cassandra/cql3/statements/CreateKeyspaceStatement.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/cql3/statements/CreateKeyspaceStatement.java b/src/java/org/apache/cassandra/cql3/statements/CreateKeyspaceStatement.java
index 9577af8..3eb0ac9 100644
--- a/src/java/org/apache/cassandra/cql3/statements/CreateKeyspaceStatement.java
+++ b/src/java/org/apache/cassandra/cql3/statements/CreateKeyspaceStatement.java
@@ -92,27 +92,22 @@ public class CreateKeyspaceStatement extends SchemaAlteringStatement
throw new ConfigurationException("Unable to use given strategy class: LocalStrategy is reserved for internal use.");
}
- public boolean announceMigration(boolean isLocalOnly) throws RequestValidationException
+ public Event.SchemaChange announceMigration(boolean isLocalOnly) throws RequestValidationException
{
KeyspaceMetadata ksm = KeyspaceMetadata.create(name, attrs.asNewKeyspaceParams());
try
{
MigrationManager.announceNewKeyspace(ksm, isLocalOnly);
- return true;
+ return new Event.SchemaChange(Event.SchemaChange.Change.CREATED, keyspace());
}
catch (AlreadyExistsException e)
{
if (ifNotExists)
- return false;
+ return null;
throw e;
}
}
- public Event.SchemaChange changeEvent()
- {
- return new Event.SchemaChange(Event.SchemaChange.Change.CREATED, keyspace());
- }
-
protected void grantPermissionsToCreator(QueryState state)
{
try
http://git-wip-us.apache.org/repos/asf/cassandra/blob/2cbd7762/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 a1947df..1363bee 100644
--- a/src/java/org/apache/cassandra/cql3/statements/CreateTableStatement.java
+++ b/src/java/org/apache/cassandra/cql3/statements/CreateTableStatement.java
@@ -78,26 +78,21 @@ public class CreateTableStatement extends SchemaAlteringStatement
// validated in announceMigration()
}
- public boolean announceMigration(boolean isLocalOnly) throws RequestValidationException
+ public Event.SchemaChange announceMigration(boolean isLocalOnly) throws RequestValidationException
{
try
{
MigrationManager.announceNewColumnFamily(getCFMetaData(), isLocalOnly);
- return true;
+ return new Event.SchemaChange(Event.SchemaChange.Change.CREATED, Event.SchemaChange.Target.TABLE, keyspace(), columnFamily());
}
catch (AlreadyExistsException e)
{
if (ifNotExists)
- return false;
+ return null;
throw e;
}
}
- public Event.SchemaChange changeEvent()
- {
- return new Event.SchemaChange(Event.SchemaChange.Change.CREATED, Event.SchemaChange.Target.TABLE, keyspace(), columnFamily());
- }
-
protected void grantPermissionsToCreator(QueryState state)
{
try
http://git-wip-us.apache.org/repos/asf/cassandra/blob/2cbd7762/src/java/org/apache/cassandra/cql3/statements/CreateTriggerStatement.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/cql3/statements/CreateTriggerStatement.java b/src/java/org/apache/cassandra/cql3/statements/CreateTriggerStatement.java
index 2589622..2720749 100644
--- a/src/java/org/apache/cassandra/cql3/statements/CreateTriggerStatement.java
+++ b/src/java/org/apache/cassandra/cql3/statements/CreateTriggerStatement.java
@@ -72,7 +72,7 @@ public class CreateTriggerStatement extends SchemaAlteringStatement
}
}
- public boolean announceMigration(boolean isLocalOnly) throws ConfigurationException, InvalidRequestException
+ public Event.SchemaChange announceMigration(boolean isLocalOnly) throws ConfigurationException, InvalidRequestException
{
CFMetaData cfm = Schema.instance.getCFMetaData(keyspace(), columnFamily()).copy();
Triggers triggers = cfm.getTriggers();
@@ -80,7 +80,7 @@ public class CreateTriggerStatement extends SchemaAlteringStatement
if (triggers.get(triggerName).isPresent())
{
if (ifNotExists)
- return false;
+ return null;
else
throw new InvalidRequestException(String.format("Trigger %s already exists", triggerName));
}
@@ -88,11 +88,6 @@ public class CreateTriggerStatement extends SchemaAlteringStatement
cfm.triggers(triggers.with(TriggerMetadata.create(triggerName, triggerClass)));
logger.info("Adding trigger with name {} and class {}", triggerName, triggerClass);
MigrationManager.announceColumnFamilyUpdate(cfm, false, isLocalOnly);
- return true;
- }
-
- public Event.SchemaChange changeEvent()
- {
return new Event.SchemaChange(Event.SchemaChange.Change.UPDATED, Event.SchemaChange.Target.TABLE, keyspace(), columnFamily());
}
}
http://git-wip-us.apache.org/repos/asf/cassandra/blob/2cbd7762/src/java/org/apache/cassandra/cql3/statements/CreateTypeStatement.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/cql3/statements/CreateTypeStatement.java b/src/java/org/apache/cassandra/cql3/statements/CreateTypeStatement.java
index 465f0f1..f62b9ea 100644
--- a/src/java/org/apache/cassandra/cql3/statements/CreateTypeStatement.java
+++ b/src/java/org/apache/cassandra/cql3/statements/CreateTypeStatement.java
@@ -93,11 +93,6 @@ public class CreateTypeStatement extends SchemaAlteringStatement
}
}
- public Event.SchemaChange changeEvent()
- {
- return new Event.SchemaChange(Event.SchemaChange.Change.CREATED, Event.SchemaChange.Target.TYPE, keyspace(), name.getStringTypeName());
- }
-
@Override
public String keyspace()
{
@@ -117,18 +112,18 @@ public class CreateTypeStatement extends SchemaAlteringStatement
return new UserType(name.getKeyspace(), name.getUserTypeName(), names, types);
}
- public boolean announceMigration(boolean isLocalOnly) throws InvalidRequestException, ConfigurationException
+ public Event.SchemaChange announceMigration(boolean isLocalOnly) throws InvalidRequestException, ConfigurationException
{
KeyspaceMetadata ksm = Schema.instance.getKSMetaData(name.getKeyspace());
assert ksm != null; // should haven't validate otherwise
// Can happen with ifNotExists
if (ksm.types.get(name.getUserTypeName()).isPresent())
- return false;
+ return null;
UserType type = createType();
checkForDuplicateNames(type);
MigrationManager.announceNewType(type, isLocalOnly);
- return true;
+ return new Event.SchemaChange(Event.SchemaChange.Change.CREATED, Event.SchemaChange.Target.TYPE, keyspace(), name.getStringTypeName());
}
}
http://git-wip-us.apache.org/repos/asf/cassandra/blob/2cbd7762/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 586b09b..5d1fd45 100644
--- a/src/java/org/apache/cassandra/cql3/statements/CreateViewStatement.java
+++ b/src/java/org/apache/cassandra/cql3/statements/CreateViewStatement.java
@@ -111,7 +111,7 @@ public class CreateViewStatement extends SchemaAlteringStatement
}
}
- public boolean announceMigration(boolean isLocalOnly) throws RequestValidationException
+ public Event.SchemaChange announceMigration(boolean isLocalOnly) throws RequestValidationException
{
// We need to make sure that:
// - primary key includes all columns in base table's primary key
@@ -292,15 +292,14 @@ public class CreateViewStatement extends SchemaAlteringStatement
try
{
MigrationManager.announceNewView(definition, isLocalOnly);
+ return new Event.SchemaChange(Event.SchemaChange.Change.CREATED, Event.SchemaChange.Target.TABLE, keyspace(), columnFamily());
}
catch (AlreadyExistsException e)
{
if (ifNotExists)
- return false;
+ return null;
throw e;
}
-
- return true;
}
private static boolean getColumnIdentifier(CFMetaData cfm,
@@ -327,9 +326,4 @@ public class CreateViewStatement extends SchemaAlteringStatement
columns.add(identifier);
return !isPk;
}
-
- public Event.SchemaChange changeEvent()
- {
- return new Event.SchemaChange(Event.SchemaChange.Change.CREATED, Event.SchemaChange.Target.TABLE, keyspace(), columnFamily());
- }
}
http://git-wip-us.apache.org/repos/asf/cassandra/blob/2cbd7762/src/java/org/apache/cassandra/cql3/statements/DropAggregateStatement.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/cql3/statements/DropAggregateStatement.java b/src/java/org/apache/cassandra/cql3/statements/DropAggregateStatement.java
index 3aa176e..bef9e74 100644
--- a/src/java/org/apache/cassandra/cql3/statements/DropAggregateStatement.java
+++ b/src/java/org/apache/cassandra/cql3/statements/DropAggregateStatement.java
@@ -44,8 +44,6 @@ public final class DropAggregateStatement extends SchemaAlteringStatement
private final List<CQL3Type.Raw> argRawTypes;
private final boolean argsPresent;
- private Function old;
-
public DropAggregateStatement(FunctionName functionName,
List<CQL3Type.Raw> argRawTypes,
boolean argsPresent,
@@ -79,13 +77,7 @@ public final class DropAggregateStatement extends SchemaAlteringStatement
{
}
- public Event.SchemaChange changeEvent()
- {
- return new Event.SchemaChange(Event.SchemaChange.Change.DROPPED, Event.SchemaChange.Target.AGGREGATE,
- old.name().keyspace, old.name().name, AbstractType.asCQLTypeStringList(old.argTypes()));
- }
-
- public boolean announceMigration(boolean isLocalOnly) throws RequestValidationException
+ public Event.SchemaChange announceMigration(boolean isLocalOnly) throws RequestValidationException
{
Collection<Function> olds = Schema.instance.getFunctions(functionName);
@@ -107,7 +99,7 @@ public final class DropAggregateStatement extends SchemaAlteringStatement
if (old == null || !(old instanceof AggregateFunction))
{
if (ifExists)
- return false;
+ return null;
// just build a nicer error message
StringBuilder sb = new StringBuilder();
for (CQL3Type.Raw rawType : argRawTypes)
@@ -125,7 +117,7 @@ public final class DropAggregateStatement extends SchemaAlteringStatement
if (olds == null || olds.isEmpty() || !(olds.iterator().next() instanceof AggregateFunction))
{
if (ifExists)
- return false;
+ return null;
throw new InvalidRequestException(String.format("Cannot drop non existing aggregate '%s'", functionName));
}
old = olds.iterator().next();
@@ -135,11 +127,10 @@ public final class DropAggregateStatement extends SchemaAlteringStatement
throw new InvalidRequestException(String.format("Cannot drop aggregate '%s' because it is a " +
"native (built-in) function", functionName));
- this.old = old;
-
MigrationManager.announceAggregateDrop((UDAggregate)old, isLocalOnly);
+ return new Event.SchemaChange(Event.SchemaChange.Change.DROPPED, Event.SchemaChange.Target.AGGREGATE,
+ old.name().keyspace, old.name().name, AbstractType.asCQLTypeStringList(old.argTypes()));
- return true;
}
private AbstractType<?> prepareType(String typeName, CQL3Type.Raw rawType)
http://git-wip-us.apache.org/repos/asf/cassandra/blob/2cbd7762/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 59864df..3cef2da 100644
--- a/src/java/org/apache/cassandra/cql3/statements/DropFunctionStatement.java
+++ b/src/java/org/apache/cassandra/cql3/statements/DropFunctionStatement.java
@@ -48,7 +48,6 @@ public final class DropFunctionStatement extends SchemaAlteringStatement
private final List<CQL3Type.Raw> argRawTypes;
private final boolean argsPresent;
- private Function old;
private List<AbstractType<?>> argTypes;
public DropFunctionStatement(FunctionName functionName,
@@ -93,7 +92,6 @@ public final class DropFunctionStatement extends SchemaAlteringStatement
ThriftValidation.validateKeyspaceNotSystem(functionName.keyspace);
}
- @Override
public void checkAccess(ClientState state) throws UnauthorizedException, InvalidRequestException
{
Function function = findFunction();
@@ -113,7 +111,6 @@ public final class DropFunctionStatement extends SchemaAlteringStatement
}
}
- @Override
public void validate(ClientState state)
{
Collection<Function> olds = Schema.instance.getFunctions(functionName);
@@ -126,21 +123,13 @@ public final class DropFunctionStatement extends SchemaAlteringStatement
functionName, functionName, functionName));
}
- @Override
- public Event.SchemaChange changeEvent()
- {
- return new Event.SchemaChange(Event.SchemaChange.Change.DROPPED, Event.SchemaChange.Target.FUNCTION,
- old.name().keyspace, old.name().name, AbstractType.asCQLTypeStringList(old.argTypes()));
- }
-
- @Override
- public boolean announceMigration(boolean isLocalOnly) throws RequestValidationException
+ public Event.SchemaChange announceMigration(boolean isLocalOnly) throws RequestValidationException
{
- old = findFunction();
+ Function old = findFunction();
if (old == null)
{
if (ifExists)
- return false;
+ return null;
else
throw new InvalidRequestException(getMissingFunctionError());
}
@@ -152,7 +141,8 @@ public final class DropFunctionStatement extends SchemaAlteringStatement
MigrationManager.announceFunctionDrop((UDFunction) old, isLocalOnly);
- return true;
+ return new Event.SchemaChange(Event.SchemaChange.Change.DROPPED, Event.SchemaChange.Target.FUNCTION,
+ old.name().keyspace, old.name().name, AbstractType.asCQLTypeStringList(old.argTypes()));
}
private String getMissingFunctionError()
http://git-wip-us.apache.org/repos/asf/cassandra/blob/2cbd7762/src/java/org/apache/cassandra/cql3/statements/DropIndexStatement.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/cql3/statements/DropIndexStatement.java b/src/java/org/apache/cassandra/cql3/statements/DropIndexStatement.java
index 63a1200..eaf755f 100644
--- a/src/java/org/apache/cassandra/cql3/statements/DropIndexStatement.java
+++ b/src/java/org/apache/cassandra/cql3/statements/DropIndexStatement.java
@@ -36,9 +36,6 @@ public class DropIndexStatement extends SchemaAlteringStatement
public final String indexName;
public final boolean ifExists;
- // initialized in announceMigration()
- private CFMetaData indexedTable;
-
public DropIndexStatement(IndexName indexName, boolean ifExists)
{
super(indexName.getCfName());
@@ -48,11 +45,8 @@ public class DropIndexStatement extends SchemaAlteringStatement
public String columnFamily()
{
- if (indexedTable != null)
- return indexedTable.cfName;
-
- indexedTable = lookupIndexedTable();
- return indexedTable == null ? null : indexedTable.cfName;
+ CFMetaData cfm = lookupIndexedTable();
+ return cfm == null ? null : cfm.cfName;
}
public void checkAccess(ClientState state) throws UnauthorizedException, InvalidRequestException
@@ -69,36 +63,39 @@ public class DropIndexStatement extends SchemaAlteringStatement
// validated in lookupIndexedTable()
}
- public Event.SchemaChange changeEvent()
- {
- // Dropping an index is akin to updating the CF
- return new Event.SchemaChange(Event.SchemaChange.Change.UPDATED, Event.SchemaChange.Target.TABLE, keyspace(), columnFamily());
- }
-
@Override
public ResultMessage execute(QueryState state, QueryOptions options) throws RequestValidationException
{
- return announceMigration(false) ? new ResultMessage.SchemaChange(changeEvent()) : null;
+ Event.SchemaChange ce = announceMigration(false);
+ return ce == null ? null : new ResultMessage.SchemaChange(ce);
}
- public boolean announceMigration(boolean isLocalOnly) throws InvalidRequestException, ConfigurationException
+ public Event.SchemaChange announceMigration(boolean isLocalOnly) throws InvalidRequestException, ConfigurationException
{
CFMetaData cfm = lookupIndexedTable();
if (cfm == null)
- return false;
+ return null;
- indexedTable = cfm;
CFMetaData updatedCfm = cfm.copy();
updatedCfm.indexes(updatedCfm.getIndexes().without(indexName));
MigrationManager.announceColumnFamilyUpdate(updatedCfm, false, isLocalOnly);
- return true;
+ // Dropping an index is akin to updating the CF
+ // Note that we shouldn't call columnFamily() at this point because the index has been dropped and the call to lookupIndexedTable()
+ // in that method would now throw.
+ return new Event.SchemaChange(Event.SchemaChange.Change.UPDATED, Event.SchemaChange.Target.TABLE, cfm.ksName, cfm.cfName);
}
+ /**
+ * The table for which the index should be dropped, or null if the index doesn't exist
+ *
+ * @return the metadata for the table containing the dropped index, or {@code null}
+ * if the index to drop cannot be found but "IF EXISTS" is set on the statement.
+ *
+ * @throws InvalidRequestException if the index cannot be found and "IF EXISTS" is not
+ * set on the statement.
+ */
private CFMetaData lookupIndexedTable()
{
- if (indexedTable != null)
- return indexedTable;
-
KeyspaceMetadata ksm = Schema.instance.getKSMetaData(keyspace());
if (ksm == null)
throw new KeyspaceNotDefinedException("Keyspace " + keyspace() + " does not exist");
http://git-wip-us.apache.org/repos/asf/cassandra/blob/2cbd7762/src/java/org/apache/cassandra/cql3/statements/DropKeyspaceStatement.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/cql3/statements/DropKeyspaceStatement.java b/src/java/org/apache/cassandra/cql3/statements/DropKeyspaceStatement.java
index ba6b917..513ff1b 100644
--- a/src/java/org/apache/cassandra/cql3/statements/DropKeyspaceStatement.java
+++ b/src/java/org/apache/cassandra/cql3/statements/DropKeyspaceStatement.java
@@ -55,23 +55,18 @@ public class DropKeyspaceStatement extends SchemaAlteringStatement
return keyspace;
}
- public boolean announceMigration(boolean isLocalOnly) throws ConfigurationException
+ public Event.SchemaChange announceMigration(boolean isLocalOnly) throws ConfigurationException
{
try
{
MigrationManager.announceKeyspaceDrop(keyspace, isLocalOnly);
- return true;
+ return new Event.SchemaChange(Event.SchemaChange.Change.DROPPED, keyspace());
}
catch(ConfigurationException e)
{
if (ifExists)
- return false;
+ return null;
throw e;
}
}
-
- public Event.SchemaChange changeEvent()
- {
- return new Event.SchemaChange(Event.SchemaChange.Change.DROPPED, keyspace());
- }
}
http://git-wip-us.apache.org/repos/asf/cassandra/blob/2cbd7762/src/java/org/apache/cassandra/cql3/statements/DropTableStatement.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/cql3/statements/DropTableStatement.java b/src/java/org/apache/cassandra/cql3/statements/DropTableStatement.java
index 1f61020..79c46f5 100644
--- a/src/java/org/apache/cassandra/cql3/statements/DropTableStatement.java
+++ b/src/java/org/apache/cassandra/cql3/statements/DropTableStatement.java
@@ -58,7 +58,7 @@ public class DropTableStatement extends SchemaAlteringStatement
// validated in announceMigration()
}
- public boolean announceMigration(boolean isLocalOnly) throws ConfigurationException
+ public Event.SchemaChange announceMigration(boolean isLocalOnly) throws ConfigurationException
{
try
{
@@ -89,18 +89,13 @@ public class DropTableStatement extends SchemaAlteringStatement
}
}
MigrationManager.announceColumnFamilyDrop(keyspace(), columnFamily(), isLocalOnly);
- return true;
+ return new Event.SchemaChange(Event.SchemaChange.Change.DROPPED, Event.SchemaChange.Target.TABLE, keyspace(), columnFamily());
}
catch (ConfigurationException e)
{
if (ifExists)
- return false;
+ return null;
throw e;
}
}
-
- public Event.SchemaChange changeEvent()
- {
- return new Event.SchemaChange(Event.SchemaChange.Change.DROPPED, Event.SchemaChange.Target.TABLE, keyspace(), columnFamily());
- }
}
http://git-wip-us.apache.org/repos/asf/cassandra/blob/2cbd7762/src/java/org/apache/cassandra/cql3/statements/DropTriggerStatement.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/cql3/statements/DropTriggerStatement.java b/src/java/org/apache/cassandra/cql3/statements/DropTriggerStatement.java
index 54711de..562b4e8 100644
--- a/src/java/org/apache/cassandra/cql3/statements/DropTriggerStatement.java
+++ b/src/java/org/apache/cassandra/cql3/statements/DropTriggerStatement.java
@@ -58,7 +58,7 @@ public class DropTriggerStatement extends SchemaAlteringStatement
ThriftValidation.validateColumnFamily(keyspace(), columnFamily());
}
- public boolean announceMigration(boolean isLocalOnly) throws ConfigurationException, InvalidRequestException
+ public Event.SchemaChange announceMigration(boolean isLocalOnly) throws ConfigurationException, InvalidRequestException
{
CFMetaData cfm = Schema.instance.getCFMetaData(keyspace(), columnFamily()).copy();
Triggers triggers = cfm.getTriggers();
@@ -66,7 +66,7 @@ public class DropTriggerStatement extends SchemaAlteringStatement
if (!triggers.get(triggerName).isPresent())
{
if (ifExists)
- return false;
+ return null;
else
throw new InvalidRequestException(String.format("Trigger %s was not found", triggerName));
}
@@ -74,11 +74,6 @@ public class DropTriggerStatement extends SchemaAlteringStatement
logger.info("Dropping trigger with name {}", triggerName);
cfm.triggers(triggers.without(triggerName));
MigrationManager.announceColumnFamilyUpdate(cfm, false, isLocalOnly);
- return true;
- }
-
- public Event.SchemaChange changeEvent()
- {
return new Event.SchemaChange(Event.SchemaChange.Change.UPDATED, Event.SchemaChange.Target.TABLE, keyspace(), columnFamily());
}
}
http://git-wip-us.apache.org/repos/asf/cassandra/blob/2cbd7762/src/java/org/apache/cassandra/cql3/statements/DropTypeStatement.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/cql3/statements/DropTypeStatement.java b/src/java/org/apache/cassandra/cql3/statements/DropTypeStatement.java
index d104b73..58abde9 100644
--- a/src/java/org/apache/cassandra/cql3/statements/DropTypeStatement.java
+++ b/src/java/org/apache/cassandra/cql3/statements/DropTypeStatement.java
@@ -124,18 +124,13 @@ public class DropTypeStatement extends SchemaAlteringStatement
return false;
}
- public Event.SchemaChange changeEvent()
- {
- return new Event.SchemaChange(Event.SchemaChange.Change.DROPPED, Event.SchemaChange.Target.TYPE, keyspace(), name.getStringTypeName());
- }
-
@Override
public String keyspace()
{
return name.getKeyspace();
}
- public boolean announceMigration(boolean isLocalOnly) throws InvalidRequestException, ConfigurationException
+ public Event.SchemaChange announceMigration(boolean isLocalOnly) throws InvalidRequestException, ConfigurationException
{
KeyspaceMetadata ksm = Schema.instance.getKSMetaData(name.getKeyspace());
assert ksm != null;
@@ -143,9 +138,9 @@ public class DropTypeStatement extends SchemaAlteringStatement
UserType toDrop = ksm.types.getNullable(name.getUserTypeName());
// Can be null with ifExists
if (toDrop == null)
- return false;
+ return null;
MigrationManager.announceTypeDrop(toDrop, isLocalOnly);
- return true;
+ return new Event.SchemaChange(Event.SchemaChange.Change.DROPPED, Event.SchemaChange.Target.TYPE, keyspace(), name.getStringTypeName());
}
}
http://git-wip-us.apache.org/repos/asf/cassandra/blob/2cbd7762/src/java/org/apache/cassandra/cql3/statements/DropViewStatement.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/cql3/statements/DropViewStatement.java b/src/java/org/apache/cassandra/cql3/statements/DropViewStatement.java
index f2be370..1f53ac4 100644
--- a/src/java/org/apache/cassandra/cql3/statements/DropViewStatement.java
+++ b/src/java/org/apache/cassandra/cql3/statements/DropViewStatement.java
@@ -53,12 +53,7 @@ public class DropViewStatement extends SchemaAlteringStatement
// validated in findIndexedCf()
}
- public Event.SchemaChange changeEvent()
- {
- return new Event.SchemaChange(Event.SchemaChange.Change.DROPPED, Event.SchemaChange.Target.TABLE, keyspace(), columnFamily());
- }
-
- public boolean announceMigration(boolean isLocalOnly) throws InvalidRequestException, ConfigurationException
+ public Event.SchemaChange announceMigration(boolean isLocalOnly) throws InvalidRequestException, ConfigurationException
{
try
{
@@ -81,12 +76,12 @@ public class DropViewStatement extends SchemaAlteringStatement
// }
MigrationManager.announceViewDrop(keyspace(), columnFamily(), isLocalOnly);
- return true;
+ return new Event.SchemaChange(Event.SchemaChange.Change.DROPPED, Event.SchemaChange.Target.TABLE, keyspace(), columnFamily());
}
catch (ConfigurationException e)
{
if (ifExists)
- return false;
+ return null;
throw e;
}
}
http://git-wip-us.apache.org/repos/asf/cassandra/blob/2cbd7762/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 a477df6..10c004c 100644
--- a/src/java/org/apache/cassandra/cql3/statements/SchemaAlteringStatement.java
+++ b/src/java/org/apache/cassandra/cql3/statements/SchemaAlteringStatement.java
@@ -65,8 +65,6 @@ public abstract class SchemaAlteringStatement extends CFStatement implements CQL
return new Prepared(this);
}
- public abstract Event.SchemaChange changeEvent();
-
/**
* Schema alteration may result in a new database object (keyspace, table, role, function) being created capable of
* having permissions GRANTed on it. The creator of the object (the primary role assigned to the AuthenticatedUser
@@ -80,29 +78,29 @@ public abstract class SchemaAlteringStatement extends CFStatement implements CQL
/**
* Announces the migration to other nodes in the cluster.
- * @return true if the execution of this statement resulted in a schema change, false otherwise (when IF NOT EXISTS
- * is used, for example)
+ *
+ * @return the schema change event corresponding to the execution of this statement, or {@code null} if no schema change
+ * has occurred (when IF NOT EXISTS is used, for example)
+ *
* @throws RequestValidationException
*/
- public abstract boolean announceMigration(boolean isLocalOnly) throws RequestValidationException;
+ public abstract Event.SchemaChange announceMigration(boolean isLocalOnly) throws RequestValidationException;
public ResultMessage execute(QueryState state, QueryOptions options) throws RequestValidationException
{
// If an IF [NOT] EXISTS clause was used, this may not result in an actual schema change. To avoid doing
// extra work in the drivers to handle schema changes, we return an empty message in this case. (CASSANDRA-7600)
- boolean didChangeSchema = announceMigration(false);
- if (!didChangeSchema)
+ Event.SchemaChange ce = announceMigration(false);
+ if (ce == null)
return new ResultMessage.Void();
- Event.SchemaChange ce = changeEvent();
-
// when a schema alteration results in a new db object being created, we grant permissions on the new
// object to the user performing the request if:
// * the user is not anonymous
// * the configured IAuthorizer supports granting of permissions (not all do, AllowAllAuthorizer doesn't and
// custom external implementations may not)
AuthenticatedUser user = state.getClientState().getUser();
- if (user != null && !user.isAnonymous() && ce != null && ce.change == Event.SchemaChange.Change.CREATED)
+ if (user != null && !user.isAnonymous() && ce.change == Event.SchemaChange.Change.CREATED)
{
try
{
@@ -114,16 +112,12 @@ public abstract class SchemaAlteringStatement extends CFStatement implements CQL
}
}
- return ce == null ? new ResultMessage.Void() : new ResultMessage.SchemaChange(ce);
+ return new ResultMessage.SchemaChange(ce);
}
public ResultMessage executeInternal(QueryState state, QueryOptions options)
{
- boolean didChangeSchema = announceMigration(true);
- if (!didChangeSchema)
- return new ResultMessage.Void();
-
- Event.SchemaChange ce = changeEvent();
+ Event.SchemaChange ce = announceMigration(true);
return ce == null ? new ResultMessage.Void() : new ResultMessage.SchemaChange(ce);
}
}
http://git-wip-us.apache.org/repos/asf/cassandra/blob/2cbd7762/test/unit/org/apache/cassandra/cql3/CQLTester.java
----------------------------------------------------------------------
diff --git a/test/unit/org/apache/cassandra/cql3/CQLTester.java b/test/unit/org/apache/cassandra/cql3/CQLTester.java
index fd0b086..fd9bb28 100644
--- a/test/unit/org/apache/cassandra/cql3/CQLTester.java
+++ b/test/unit/org/apache/cassandra/cql3/CQLTester.java
@@ -78,6 +78,7 @@ public abstract class CQLTester
public static final String KEYSPACE = "cql_test_keyspace";
public static final String KEYSPACE_PER_TEST = "cql_test_keyspace_alt";
protected static final boolean USE_PREPARED_VALUES = Boolean.valueOf(System.getProperty("cassandra.test.use_prepared", "true"));
+ protected static final boolean REUSE_PREPARED = Boolean.valueOf(System.getProperty("cassandra.test.reuse_prepared", "true"));
protected static final long ROW_CACHE_SIZE_IN_MB = Integer.valueOf(System.getProperty("cassandra.test.row_cache_size_in_mb", "0"));
private static final AtomicInteger seqNumber = new AtomicInteger();
@@ -137,6 +138,7 @@ public abstract class CQLTester
// We don't use USE_PREPARED_VALUES in the code below so some test can foce value preparation (if the result
// is not expected to be the same without preparation)
private boolean usePrepared = USE_PREPARED_VALUES;
+ private static boolean reusePrepared = REUSE_PREPARED;
public static void prepareServer()
{
@@ -236,6 +238,11 @@ public abstract class CQLTester
if (server != null)
server.stop();
+
+ // We use queryInternal for CQLTester so prepared statement will populate our internal cache (if reusePrepared is used; otherwise prepared
+ // statements are not cached but re-prepared every time). So we clear the cache between test files to avoid accumulating too much.
+ if (reusePrepared)
+ QueryProcessor.clearInternalStatementsCache();
}
@Before
@@ -252,6 +259,7 @@ public abstract class CQLTester
// Restore standard behavior in case it was changed
usePrepared = USE_PREPARED_VALUES;
+ reusePrepared = REUSE_PREPARED;
final List<String> tablesToDrop = copy(tables);
final List<String> typesToDrop = copy(types);
@@ -447,6 +455,11 @@ public abstract class CQLTester
this.usePrepared = USE_PREPARED_VALUES;
}
+ protected void disablePreparedReuseForTest()
+ {
+ this.reusePrepared = false;
+ }
+
protected String createType(String query)
{
String typeName = "type_" + seqNumber.getAndIncrement();
@@ -655,7 +668,21 @@ public abstract class CQLTester
{
if (logger.isDebugEnabled())
logger.debug("Executing: {} with values {}", query, formatAllValues(values));
- rs = QueryProcessor.executeOnceInternal(query, transformValues(values));
+ if (reusePrepared)
+ {
+ rs = QueryProcessor.executeInternal(query, transformValues(values));
+
+ // If a test uses a "USE ...", then presumably its statements use relative table. In that case, a USE
+ // change the meaning of the current keyspace, so we don't want a following statement to reuse a previously
+ // prepared statement at this wouldn't use the right keyspace. To avoid that, we drop the previously
+ // prepared statement.
+ if (query.startsWith("USE"))
+ QueryProcessor.clearInternalStatementsCache();
+ }
+ else
+ {
+ rs = QueryProcessor.executeOnceInternal(query, transformValues(values));
+ }
}
else
{
http://git-wip-us.apache.org/repos/asf/cassandra/blob/2cbd7762/test/unit/org/apache/cassandra/cql3/validation/entities/SecondaryIndexTest.java
----------------------------------------------------------------------
diff --git a/test/unit/org/apache/cassandra/cql3/validation/entities/SecondaryIndexTest.java b/test/unit/org/apache/cassandra/cql3/validation/entities/SecondaryIndexTest.java
index 225e197..d30937f 100644
--- a/test/unit/org/apache/cassandra/cql3/validation/entities/SecondaryIndexTest.java
+++ b/test/unit/org/apache/cassandra/cql3/validation/entities/SecondaryIndexTest.java
@@ -23,6 +23,7 @@ import java.util.*;
import org.apache.cassandra.db.DeletionTime;
import org.apache.cassandra.utils.Pair;
import org.apache.commons.lang3.StringUtils;
+import org.junit.Before;
import org.junit.Test;
import org.apache.cassandra.config.CFMetaData;
@@ -53,6 +54,14 @@ public class SecondaryIndexTest extends CQLTester
{
private static final int TOO_BIG = 1024 * 65;
+ @Before
+ public void disablePreparedReuse() throws Throwable
+ {
+ // TODO: this shouldn't be needed but is due to #10758. As such, this should be removed on that
+ // ticket is fixed.
+ disablePreparedReuseForTest();
+ }
+
@Test
public void testCreateAndDropIndex() throws Throwable
{
http://git-wip-us.apache.org/repos/asf/cassandra/blob/2cbd7762/test/unit/org/apache/cassandra/index/internal/CassandraIndexTest.java
----------------------------------------------------------------------
diff --git a/test/unit/org/apache/cassandra/index/internal/CassandraIndexTest.java b/test/unit/org/apache/cassandra/index/internal/CassandraIndexTest.java
index 934e551..c72b4ec 100644
--- a/test/unit/org/apache/cassandra/index/internal/CassandraIndexTest.java
+++ b/test/unit/org/apache/cassandra/index/internal/CassandraIndexTest.java
@@ -24,6 +24,7 @@ import java.util.stream.StreamSupport;
import com.google.common.base.Joiner;
import com.google.common.collect.*;
+import org.junit.Before;
import org.junit.Test;
import org.apache.cassandra.config.CFMetaData;
@@ -55,6 +56,13 @@ import static org.junit.Assert.fail;
*/
public class CassandraIndexTest extends CQLTester
{
+ @Before
+ public void disablePreparedReuse() throws Throwable
+ {
+ // TODO: this shouldn't be needed but is due to #10758. As such, this should be removed on that
+ // ticket is fixed.
+ disablePreparedReuseForTest();
+ }
@Test
public void indexOnRegularColumn() throws Throwable