Skip to content

Commit

Permalink
STAR-1097 Store Raw CQL query inside statement (apache#333)
Browse files Browse the repository at this point in the history
Original CQL string is needed in the implementation of Query
intercepter (STAR-1112). Converged Cassandra stored it in
QueryHandler.Prepared, which is difficult to access. It seems that it
is more straightforward to move storing CQL string into statements.

This commit changes to store query strings in statements and adds an
access method to the string to CQLStatement.

(cherry picked from commit ab7fbd2)
(cherry picked from commit af67f2b)
(cherry picked from commit 3a52a9a)
  • Loading branch information
k-rus authored and jacek-lewandowski committed Oct 18, 2022
1 parent fc74b0d commit 85c6a78
Show file tree
Hide file tree
Showing 38 changed files with 222 additions and 132 deletions.
9 changes: 5 additions & 4 deletions src/java/org/apache/cassandra/auth/CassandraAuthorizer.java
Expand Up @@ -178,10 +178,11 @@ public void revokeAllOn(IResource droppedResource)
private void executeLoggedBatch(List<CQLStatement> statements)
throws RequestExecutionException, RequestValidationException
{
BatchStatement batch = new BatchStatement(BatchStatement.Type.LOGGED,
VariableSpecifications.empty(),
Lists.newArrayList(Iterables.filter(statements, ModificationStatement.class)),
Attributes.none());
BatchStatement batch = new BatchStatement(null,
BatchStatement.Type.LOGGED,
VariableSpecifications.empty(),
Lists.newArrayList(Iterables.filter(statements, ModificationStatement.class)),
Attributes.none());
processBatch(batch);
}

Expand Down
19 changes: 19 additions & 0 deletions src/java/org/apache/cassandra/cql3/CQLStatement.java
Expand Up @@ -28,6 +28,14 @@

public interface CQLStatement
{
/**
* The query string that produced that statement, if available.
*
* @return the raw query string that produced that statement, or {@code null} if said string is not available
* (typically because the statement has not be built from a string). Note that said string may contain bind markers.
*/
public String getRawCQLStatement();

/**
* Returns all bind variables for the statement
*/
Expand Down Expand Up @@ -101,8 +109,19 @@ default public boolean hasConditions()

public static abstract class Raw
{
protected String rawCQLStatement;
protected VariableSpecifications bindVariables;

public void setRawCQLStatement(String queryString)
{
this.rawCQLStatement = queryString;
}

public String getRawCQLStatement()
{
return rawCQLStatement;
}

public void setBindVariables(List<ColumnIdentifier> variables)
{
bindVariables = new VariableSpecifications(variables);
Expand Down
8 changes: 4 additions & 4 deletions src/java/org/apache/cassandra/cql3/QueryEvents.java
Expand Up @@ -104,14 +104,14 @@ public void notifyQueryFailure(CQLStatement statement,
}

public void notifyExecuteSuccess(CQLStatement statement,
String query,
QueryOptions options,
QueryState state,
long queryTime,
Message.Response response)
{
try
{
String query = statement.getRawCQLStatement();
final String maybeObfuscatedQuery = listeners.size() > 0 ? maybeObfuscatePassword(statement, query) : query;
for (Listener listener : listeners)
listener.executeSuccess(statement, maybeObfuscatedQuery, options, state, queryTime, response);
Expand All @@ -129,7 +129,7 @@ public void notifyExecuteFailure(QueryHandler.Prepared prepared,
Exception cause)
{
CQLStatement statement = prepared != null ? prepared.statement : null;
String query = prepared != null ? prepared.rawCQLStatement : null;
String query = prepared != null ? prepared.statement.getRawCQLStatement() : null;
try
{
final String maybeObfuscatedQuery = listeners.size() > 0 ? maybeObfuscatePassword(statement, query) : query;
Expand Down Expand Up @@ -180,7 +180,7 @@ public void notifyBatchFailure(List<QueryHandler.Prepared> prepared,
{
prepared.forEach(p -> {
statements.add(p.statement);
queries.add(p.rawCQLStatement);
queries.add(p.statement.getRawCQLStatement());
});
}
try
Expand Down Expand Up @@ -242,7 +242,7 @@ public void notifyPrepareFailure(@Nullable CQLStatement statement, String query,
}
}

private String maybeObfuscatePassword(CQLStatement statement, String query)
private String maybeObfuscatePassword(@Nullable CQLStatement statement, String query)
{
// Statement might be null as side-effect of failed parsing, originates from QueryMessage#execute
if (statement == null)
Expand Down
4 changes: 1 addition & 3 deletions src/java/org/apache/cassandra/cql3/QueryHandler.java
Expand Up @@ -67,14 +67,12 @@ public static class Prepared
* {@link QueryHandler#prepare(String, ClientState, Map)}.
* Other usages of this class may or may not contain the CQL statement source.
*/
public final String rawCQLStatement;
public final String keyspace;
public final boolean fullyQualified;

public Prepared(CQLStatement statement, String rawCQLStatement, boolean fullyQualified, String keyspace)
public Prepared(CQLStatement statement, boolean fullyQualified, String keyspace)
{
this.statement = statement;
this.rawCQLStatement = rawCQLStatement;
this.resultMetadataId = ResultSet.ResultMetadata.fromPrepared(statement).getResultMetadataId();
this.fullyQualified = fullyQualified;
this.keyspace = keyspace;
Expand Down
13 changes: 6 additions & 7 deletions src/java/org/apache/cassandra/cql3/QueryProcessor.java
Expand Up @@ -440,10 +440,7 @@ public static Prepared parseAndPrepare(String query, ClientState clientState, bo
CQLStatement statement = raw.prepare(clientState);
statement.validate(new QueryState(clientState));

if (isInternal)
return new Prepared(statement, "", fullyQualified, keyspace);
else
return new Prepared(statement, query, fullyQualified, keyspace);
return new Prepared(statement, fullyQualified, keyspace);
}

public static UntypedResultSet executeInternal(String query, Object... values)
Expand Down Expand Up @@ -681,8 +678,8 @@ public static ResultMessage.Prepared getStoredPreparedStatement(String queryStri
if (existing == null)
return null;

checkTrue(queryString.equals(existing.rawCQLStatement),
String.format("MD5 hash collision: query with the same MD5 hash was already prepared. \n Existing: '%s'", existing.rawCQLStatement));
checkTrue(queryString.equals(existing.statement.getRawCQLStatement()),
String.format("MD5 hash collision: query with the same MD5 hash was already prepared. \n Existing: '%s'", existing.statement.getRawCQLStatement()));

return createResultMessage(statementId, existing);
}
Expand Down Expand Up @@ -805,7 +802,9 @@ public static CQLStatement.Raw parseStatement(String queryStr) throws SyntaxExce
{
try
{
return CQLFragmentParser.parseAnyUnhandled(CqlParser::query, queryStr);
CQLStatement.Raw stmt = CQLFragmentParser.parseAnyUnhandled(CqlParser::query, queryStr);
stmt.setRawCQLStatement(queryStr);
return stmt;
}
catch (CassandraException ce)
{
Expand Down
16 changes: 11 additions & 5 deletions src/java/org/apache/cassandra/cql3/statements/BatchStatement.java
Expand Up @@ -39,7 +39,6 @@

import org.apache.cassandra.audit.AuditLogContext;
import org.apache.cassandra.audit.AuditLogEntryType;
import org.apache.cassandra.config.DatabaseDescriptor;
import org.apache.cassandra.cql3.Attributes;
import org.apache.cassandra.cql3.BatchQueryOptions;
import org.apache.cassandra.cql3.CQLStatement;
Expand Down Expand Up @@ -69,9 +68,7 @@
import org.apache.cassandra.service.ClientWarn;
import org.apache.cassandra.service.QueryState;
import org.apache.cassandra.service.StorageProxy;
import org.apache.cassandra.tracing.Tracing;
import org.apache.cassandra.transport.messages.ResultMessage;
import org.apache.cassandra.utils.FBUtilities;
import org.apache.cassandra.utils.NoSpamLogger;
import org.apache.cassandra.utils.Pair;

Expand All @@ -88,6 +85,7 @@ public enum Type
LOGGED, UNLOGGED, COUNTER
}

private final String rawCQLStatement;
public final Type type;
private final VariableSpecifications bindVariables;
private final List<ModificationStatement> statements;
Expand Down Expand Up @@ -120,8 +118,10 @@ public enum Type
* @param statements the list of statements in the batch
* @param attrs additional attributes for statement (CL, timestamp, timeToLive)
*/
public BatchStatement(Type type, VariableSpecifications bindVariables, List<ModificationStatement> statements, Attributes attrs)
public BatchStatement(String queryString, Type type, VariableSpecifications bindVariables,
List<ModificationStatement> statements, Attributes attrs)
{
this.rawCQLStatement = queryString;
this.type = type;
this.bindVariables = bindVariables;
this.statements = statements;
Expand Down Expand Up @@ -155,6 +155,12 @@ public BatchStatement(Type type, VariableSpecifications bindVariables, List<Modi
this.updatesVirtualTables = updatesVirtualTables;
}

@Override
public String getRawCQLStatement()
{
return rawCQLStatement;
}

@Override
public List<ColumnSpecification> getBindVariables()
{
Expand Down Expand Up @@ -660,7 +666,7 @@ public BatchStatement prepare(ClientState state)
Attributes prepAttrs = attrs.prepare("[batch]", "[batch]");
prepAttrs.collectMarkerSpecification(bindVariables);

BatchStatement batchStatement = new BatchStatement(type, bindVariables, statements, prepAttrs);
BatchStatement batchStatement = new BatchStatement(rawCQLStatement, type, bindVariables, statements, prepAttrs);
batchStatement.validate();

return batchStatement;
Expand Down
Expand Up @@ -43,14 +43,15 @@
*/
public class DeleteStatement extends ModificationStatement
{
private DeleteStatement(VariableSpecifications bindVariables,
private DeleteStatement(String queryString,
VariableSpecifications bindVariables,
TableMetadata cfm,
Operations operations,
StatementRestrictions restrictions,
Conditions conditions,
Attributes attrs)
{
super(StatementType.DELETE, bindVariables, cfm, operations, restrictions, conditions, attrs);
super(queryString, StatementType.DELETE, bindVariables, cfm, operations, restrictions, conditions, attrs);
}

@Override
Expand Down Expand Up @@ -168,7 +169,8 @@ protected ModificationStatement prepareInternal(TableMetadata metadata,
whereClause,
conditions);

DeleteStatement stmt = new DeleteStatement(bindVariables,
DeleteStatement stmt = new DeleteStatement(rawCQLStatement,
bindVariables,
metadata,
operations,
restrictions,
Expand Down
Expand Up @@ -86,6 +86,8 @@ public abstract class ModificationStatement implements CQLStatement.SingleKeyspa

private static final ColumnIdentifier CAS_RESULT_COLUMN = new ColumnIdentifier("[applied]", false);

private final String rawCQLStatement;

protected final StatementType type;

protected final VariableSpecifications bindVariables;
Expand All @@ -105,14 +107,16 @@ public abstract class ModificationStatement implements CQLStatement.SingleKeyspa

private final RegularAndStaticColumns requiresRead;

public ModificationStatement(StatementType type,
public ModificationStatement(String queryString,
StatementType type,
VariableSpecifications bindVariables,
TableMetadata metadata,
Operations operations,
StatementRestrictions restrictions,
Conditions conditions,
Attributes attrs)
{
this.rawCQLStatement = queryString;
this.type = type;
this.bindVariables = bindVariables;
this.metadata = metadata;
Expand Down Expand Up @@ -160,6 +164,12 @@ public ModificationStatement(StatementType type,
this.requiresRead = requiresReadBuilder.build();
}

@Override
public String getRawCQLStatement()
{
return rawCQLStatement;
}

@Override
public List<ColumnSpecification> getBindVariables()
{
Expand Down
17 changes: 14 additions & 3 deletions src/java/org/apache/cassandra/cql3/statements/SelectStatement.java
Expand Up @@ -95,6 +95,7 @@ public class SelectStatement implements CQLStatement.SingleKeyspaceCqlStatement
{
private static final Logger logger = LoggerFactory.getLogger(SelectStatement.class);

private final String rawCQLStatement;
public final VariableSpecifications bindVariables;
public final TableMetadata table;
public final Parameters parameters;
Expand Down Expand Up @@ -123,7 +124,8 @@ public class SelectStatement implements CQLStatement.SingleKeyspaceCqlStatement
false,
false);

public SelectStatement(TableMetadata table,
public SelectStatement(String queryString,
TableMetadata table,
VariableSpecifications bindVariables,
Parameters parameters,
Selection selection,
Expand All @@ -134,6 +136,7 @@ public SelectStatement(TableMetadata table,
Term limit,
Term perPartitionLimit)
{
this.rawCQLStatement = queryString;
this.table = table;
this.bindVariables = bindVariables;
this.selection = selection;
Expand All @@ -146,6 +149,12 @@ public SelectStatement(TableMetadata table,
this.perPartitionLimit = perPartitionLimit;
}

@Override
public String getRawCQLStatement()
{
return rawCQLStatement;
}

@Override
public List<ColumnSpecification> getBindVariables()
{
Expand Down Expand Up @@ -192,7 +201,8 @@ public ColumnFilter queriedColumns()
// queried data through processColumnFamily.
static SelectStatement forSelection(TableMetadata table, Selection selection)
{
return new SelectStatement(table,
return new SelectStatement(null,
table,
VariableSpecifications.empty(),
defaultParameters,
selection,
Expand Down Expand Up @@ -1036,7 +1046,8 @@ public SelectStatement prepare(boolean forView) throws InvalidRequestException

checkNeedsFiltering(table, restrictions);

return new SelectStatement(table,
return new SelectStatement(rawCQLStatement,
table,
bindVariables,
parameters,
selection,
Expand Down
Expand Up @@ -48,15 +48,16 @@ public class UpdateStatement extends ModificationStatement
{
private static final Constants.Value EMPTY = new Constants.Value(ByteBufferUtil.EMPTY_BYTE_BUFFER);

private UpdateStatement(StatementType type,
private UpdateStatement(String queryString,
StatementType type,
VariableSpecifications bindVariables,
TableMetadata metadata,
Operations operations,
StatementRestrictions restrictions,
Conditions conditions,
Attributes attrs)
{
super(type, bindVariables, metadata, operations, restrictions, conditions, attrs);
super(queryString, type, bindVariables, metadata, operations, restrictions, conditions, attrs);
}

@Override
Expand Down Expand Up @@ -184,7 +185,8 @@ protected ModificationStatement prepareInternal(TableMetadata metadata,
false,
false);

return new UpdateStatement(type,
return new UpdateStatement(rawCQLStatement,
type,
bindVariables,
metadata,
operations,
Expand Down Expand Up @@ -252,7 +254,8 @@ protected ModificationStatement prepareInternal(TableMetadata metadata,
false,
false);

return new UpdateStatement(type,
return new UpdateStatement(rawCQLStatement,
type,
bindVariables,
metadata,
operations,
Expand Down Expand Up @@ -315,7 +318,8 @@ protected ModificationStatement prepareInternal(TableMetadata metadata,
whereClause,
conditions);

return new UpdateStatement(type,
return new UpdateStatement(rawCQLStatement,
type,
bindVariables,
metadata,
operations,
Expand Down

0 comments on commit 85c6a78

Please sign in to comment.