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;
     }
 
     /**


Reply via email to