Author: eevans
Date: Mon Dec 19 16:50:35 2011
New Revision: 1220840
URL: http://svn.apache.org/viewvc?rev=1220840&view=rev
Log:
index bind markers using parser
Patch by eevans; reviewed by Rick Shaw for CASSANDRA-2475
Modified:
cassandra/trunk/src/java/org/apache/cassandra/cql/CQLStatement.java
cassandra/trunk/src/java/org/apache/cassandra/cql/Cql.g
cassandra/trunk/src/java/org/apache/cassandra/cql/QueryProcessor.java
cassandra/trunk/src/java/org/apache/cassandra/cql/Term.java
Modified: cassandra/trunk/src/java/org/apache/cassandra/cql/CQLStatement.java
URL:
http://svn.apache.org/viewvc/cassandra/trunk/src/java/org/apache/cassandra/cql/CQLStatement.java?rev=1220840&r1=1220839&r2=1220840&view=diff
==============================================================================
--- cassandra/trunk/src/java/org/apache/cassandra/cql/CQLStatement.java
(original)
+++ cassandra/trunk/src/java/org/apache/cassandra/cql/CQLStatement.java Mon Dec
19 16:50:35 2011
@@ -26,9 +26,10 @@ public class CQLStatement
public Object statement;
public int boundTerms = 0;
- public CQLStatement(StatementType type, Object statement)
+ public CQLStatement(StatementType type, Object statement, int lastMarker)
{
this.type = type;
this.statement = statement;
+ this.boundTerms = lastMarker + 1;
}
}
Modified: cassandra/trunk/src/java/org/apache/cassandra/cql/Cql.g
URL:
http://svn.apache.org/viewvc/cassandra/trunk/src/java/org/apache/cassandra/cql/Cql.g?rev=1220840&r1=1220839&r2=1220840&view=diff
==============================================================================
--- cassandra/trunk/src/java/org/apache/cassandra/cql/Cql.g (original)
+++ cassandra/trunk/src/java/org/apache/cassandra/cql/Cql.g Mon Dec 19 16:50:35
2011
@@ -42,6 +42,7 @@ options {
@members {
private List<String> recognitionErrors = new ArrayList<String>();
+ private int currentBindMarkerIdx = -1;
public void displayRecognitionError(String[] tokenNames,
RecognitionException e)
{
@@ -111,20 +112,20 @@ options {
}
query returns [CQLStatement stmnt]
- : selectStatement { $stmnt = new CQLStatement(StatementType.SELECT,
$selectStatement.expr); }
- | insertStatement endStmnt { $stmnt = new
CQLStatement(StatementType.INSERT, $insertStatement.expr); }
- | updateStatement endStmnt { $stmnt = new
CQLStatement(StatementType.UPDATE, $updateStatement.expr); }
- | batchStatement { $stmnt = new CQLStatement(StatementType.BATCH,
$batchStatement.expr); }
- | useStatement { $stmnt = new CQLStatement(StatementType.USE,
$useStatement.keyspace); }
- | truncateStatement { $stmnt = new CQLStatement(StatementType.TRUNCATE,
$truncateStatement.cf); }
- | deleteStatement endStmnt { $stmnt = new
CQLStatement(StatementType.DELETE, $deleteStatement.expr); }
- | createKeyspaceStatement { $stmnt = new
CQLStatement(StatementType.CREATE_KEYSPACE, $createKeyspaceStatement.expr); }
- | createColumnFamilyStatement { $stmnt = new
CQLStatement(StatementType.CREATE_COLUMNFAMILY,
$createColumnFamilyStatement.expr); }
- | createIndexStatement { $stmnt = new
CQLStatement(StatementType.CREATE_INDEX, $createIndexStatement.expr); }
- | dropIndexStatement { $stmnt = new
CQLStatement(StatementType.DROP_INDEX, $dropIndexStatement.expr); }
- | dropKeyspaceStatement { $stmnt = new
CQLStatement(StatementType.DROP_KEYSPACE, $dropKeyspaceStatement.ksp); }
- | dropColumnFamilyStatement { $stmnt = new
CQLStatement(StatementType.DROP_COLUMNFAMILY, $dropColumnFamilyStatement.cfam);
}
- | alterTableStatement { $stmnt = new
CQLStatement(StatementType.ALTER_TABLE, $alterTableStatement.expr); }
+ : selectStatement { $stmnt = new CQLStatement(StatementType.SELECT,
$selectStatement.expr, currentBindMarkerIdx); }
+ | insertStatement endStmnt { $stmnt = new
CQLStatement(StatementType.INSERT, $insertStatement.expr,
currentBindMarkerIdx); }
+ | updateStatement endStmnt { $stmnt = new
CQLStatement(StatementType.UPDATE, $updateStatement.expr,
currentBindMarkerIdx); }
+ | batchStatement { $stmnt = new CQLStatement(StatementType.BATCH,
$batchStatement.expr, currentBindMarkerIdx); }
+ | useStatement { $stmnt = new CQLStatement(StatementType.USE,
$useStatement.keyspace, currentBindMarkerIdx); }
+ | truncateStatement { $stmnt = new CQLStatement(StatementType.TRUNCATE,
$truncateStatement.cf, currentBindMarkerIdx); }
+ | deleteStatement endStmnt { $stmnt = new
CQLStatement(StatementType.DELETE, $deleteStatement.expr,
currentBindMarkerIdx); }
+ | createKeyspaceStatement { $stmnt = new
CQLStatement(StatementType.CREATE_KEYSPACE, $createKeyspaceStatement.expr,
currentBindMarkerIdx); }
+ | createColumnFamilyStatement { $stmnt = new
CQLStatement(StatementType.CREATE_COLUMNFAMILY,
$createColumnFamilyStatement.expr, currentBindMarkerIdx); }
+ | createIndexStatement { $stmnt = new
CQLStatement(StatementType.CREATE_INDEX, $createIndexStatement.expr,
currentBindMarkerIdx); }
+ | dropIndexStatement { $stmnt = new
CQLStatement(StatementType.DROP_INDEX, $dropIndexStatement.expr,
currentBindMarkerIdx); }
+ | dropKeyspaceStatement { $stmnt = new
CQLStatement(StatementType.DROP_KEYSPACE, $dropKeyspaceStatement.ksp,
currentBindMarkerIdx); }
+ | dropColumnFamilyStatement { $stmnt = new
CQLStatement(StatementType.DROP_COLUMNFAMILY, $dropColumnFamilyStatement.cfam,
currentBindMarkerIdx); }
+ | alterTableStatement { $stmnt = new
CQLStatement(StatementType.ALTER_TABLE, $alterTableStatement.expr,
currentBindMarkerIdx); }
;
// USE <KEYSPACE>;
@@ -450,7 +451,9 @@ comparatorType
;
term returns [Term item]
- : ( t=K_KEY | t=STRING_LITERAL | t=INTEGER | t=UUID | t=IDENT | t=FLOAT |
t=QMARK) { $item = new Term($t.text, $t.type); }
+ : (( t=K_KEY | t=STRING_LITERAL | t=INTEGER | t=UUID | t=IDENT | t=FLOAT )
{ $item = new Term($t.text, $t.type); }
+ | t=QMARK { $item = new Term($t.text, $t.type, ++currentBindMarkerIdx);
}
+ )
;
termList returns [List<Term> items]
Modified: cassandra/trunk/src/java/org/apache/cassandra/cql/QueryProcessor.java
URL:
http://svn.apache.org/viewvc/cassandra/trunk/src/java/org/apache/cassandra/cql/QueryProcessor.java?rev=1220840&r1=1220839&r2=1220840&view=diff
==============================================================================
--- cassandra/trunk/src/java/org/apache/cassandra/cql/QueryProcessor.java
(original)
+++ cassandra/trunk/src/java/org/apache/cassandra/cql/QueryProcessor.java Mon
Dec 19 16:50:35 2011
@@ -494,120 +494,6 @@ public class QueryProcessor
Predicates.not(Predicates.equalTo(StorageProxy.UNREACHABLE)));
}
-
- private final static void maybeAddBoundTerm(CQLStatement statement, Term
term) throws InvalidRequestException
- {
- if (term != null && term.isBindMarker())
- term.setBindIndex(statement.boundTerms++);
- }
-
- private static void discoverBoundTerms(CQLStatement statement) throws
InvalidRequestException
- {
- switch (statement.type)
- {
- case SELECT:
- SelectStatement select = (SelectStatement)statement.statement;
- if (logger.isTraceEnabled()) logger.trace(select.toString());
-
- // handle the select expression first
- if (!select.isColumnRange())
- {
- for (Term term : select.getColumnNames())
- maybeAddBoundTerm(statement,term);
- }
- else
- {
- maybeAddBoundTerm(statement, select.getColumnStart());
- maybeAddBoundTerm(statement, select.getColumnFinish());
- }
-
- // next handle the WHERE clause NB order is VERY important
-
- // first check for a multi-key (IN) list
-
- if (select.isMultiKey())
- {
- for (Term term : select.getKeys())
maybeAddBoundTerm(statement, term);
- }
- else if (!select.getColumnRelations().isEmpty())
- {
- if (select.isKeyRange())
- {
- maybeAddBoundTerm(statement, select.getKeyStart());
- maybeAddBoundTerm(statement, select.getKeyFinish());
- }
-
- for (Relation relation : select.getColumnRelations())
- {
- maybeAddBoundTerm(statement, relation.getEntity());
- maybeAddBoundTerm(statement, relation.getValue());
- }
- }
- else
- {
- // maybe its empty or just a simple term
- for (Term term : select.getKeys())
maybeAddBoundTerm(statement, term);
- }
-
- break;
-
- case UPDATE:
- UpdateStatement update = (UpdateStatement)statement.statement;
- if (logger.isTraceEnabled()) logger.trace(update.toString());
-
- // first handle the SET clause values that come in pairs for
UPDATE. NB the order of the markers (?)
- for (Map.Entry<Term, Operation> column :
update.getColumns().entrySet())
- {
- maybeAddBoundTerm(statement, column.getKey());
- maybeAddBoundTerm(statement, column.getValue().a);
- }
-
- // now handle the key(s) in the WHERE clause
-
- for (Term term : update.getKeys())
maybeAddBoundTerm(statement, term);
- break;
-
- case INSERT: // insert uses UpdateStatement but with different
marker ordering
- UpdateStatement insert = (UpdateStatement)statement.statement;
- if (logger.isTraceEnabled()) logger.trace(insert.toString());
-
- // first handle the INTO..VALUES clause values that are
grouped in order for INSERT. NB the order of the markers (?)
- for (Term term : insert.getColumnNames())
maybeAddBoundTerm(statement, term);
- for (Term term : insert.getColumnValues())
maybeAddBoundTerm(statement, term);
-
- // now handle the key(s) in the VALUES clause
- for (Term term : insert.getKeys())
maybeAddBoundTerm(statement, term);
- break;
-
- case DELETE:
- DeleteStatement delete = (DeleteStatement)statement.statement;
- if (logger.isTraceEnabled()) logger.trace(delete.toString());
-
- // first handle the columns list for DELETE. NB the order of
the markers (?)
- for (Term term : delete.getColumns())
maybeAddBoundTerm(statement, term);
-
- // now handle the key(s) in the WHERE clause
- for (Term term : delete.getKeys())
maybeAddBoundTerm(statement, term);
- break;
-
- case CREATE_COLUMNFAMILY:
- CreateColumnFamilyStatement createCf =
(CreateColumnFamilyStatement)statement.statement;
-
- // handle the left hand Terms. Not terribly useful but
included for completeness
- for (Term term : createCf.getColumns().keySet())
maybeAddBoundTerm(statement, term);
- break;
-
- case CREATE_INDEX:
- CreateIndexStatement createIdx =
(CreateIndexStatement)statement.statement;
-
- // handle the column name Term. Not terribly useful but
included for completeness
- maybeAddBoundTerm(statement, createIdx.getColumnName());
- break;
-
- default: // all other statement types are a NOOP.
- }
- }
-
public static CqlResult processStatement(CQLStatement
statement,ClientState clientState, List<String> variables )
throws UnavailableException, InvalidRequestException, TimedOutException,
SchemaDisagreementException
{
@@ -1101,15 +987,12 @@ public class QueryProcessor
CQLStatement statement = getStatement(queryString);
int statementId = makeStatementId(queryString);
-
- discoverBoundTerms(statement);
- if (logger.isTraceEnabled()) logger.trace("Discovered "+
statement.boundTerms + " bound variables.");
+ logger.trace("Discovered "+ statement.boundTerms + " bound
variables.");
clientState.getPrepared().put(statementId, statement);
- if (logger.isTraceEnabled())
- logger.trace(String.format("Stored prepared statement #%d with %d
bind markers",
- statementId,
- statement.boundTerms));
+ logger.trace(String.format("Stored prepared statement #%d with %d bind
markers",
+ statementId,
+ statement.boundTerms));
return new CqlPreparedResult(statementId, statement.boundTerms);
}
@@ -1121,13 +1004,15 @@ public class QueryProcessor
if (!(variables.isEmpty() && (statement.boundTerms == 0)))
{
if (variables.size() != statement.boundTerms)
- throw new InvalidRequestException(String.format("there were %d
markers(?) in CQL but %d bound variables",
-
statement.boundTerms, variables.size()));
+ throw new InvalidRequestException(String.format("there were %d
markers(?) in CQL but %d bound variables",
+
statement.boundTerms,
+
variables.size()));
// at this point there is a match in count between markers and
variables that is non-zero
if (logger.isTraceEnabled())
- for (int i = 0; i < variables.size(); i++) logger.trace("[{}]
'{}'", i+1, variables.get(i));
+ for (int i = 0; i < variables.size(); i++)
+ logger.trace("[{}] '{}'", i+1, variables.get(i));
}
return processStatement(statement, clientState, variables);
Modified: cassandra/trunk/src/java/org/apache/cassandra/cql/Term.java
URL:
http://svn.apache.org/viewvc/cassandra/trunk/src/java/org/apache/cassandra/cql/Term.java?rev=1220840&r1=1220839&r2=1220840&view=diff
==============================================================================
--- cassandra/trunk/src/java/org/apache/cassandra/cql/Term.java (original)
+++ cassandra/trunk/src/java/org/apache/cassandra/cql/Term.java Mon Dec 19
16:50:35 2011
@@ -33,11 +33,10 @@ import org.apache.cassandra.thrift.Inval
/** A term parsed from a CQL statement. */
public class Term
-{
+{
private final String text;
private final TermType type;
-
- private Integer bindIndex;
+ private Integer bindIndex = -1;
/**
* Create new Term instance from a string, and an integer that corresponds
@@ -70,9 +69,10 @@ public class Term
this.type = TermType.STRING;
}
- public void setBindIndex(int bindIndex)
+ public Term(String text, int type, int index)
{
- this.bindIndex = bindIndex;
+ this(text, type);
+ this.bindIndex = index;
}
/**