@ Override public QueryResult < CqlRows < K , N , V > > execute ( ) { return new QueryResultImpl < CqlRows < K , N , V > > ( keyspace . doExecuteOperation ( new Operation < CqlRows < K , N , V > > ( OperationType . READ ) { @ Override public CqlRows < K , N , V > execute ( Client cassandra ) throws HectorException { CqlRows < K , N , V > rows = null ; try { if ( cqlVersion != null ) { cassandra . set_cql_version ( cqlVersion ) ; } CqlResult result = null ; if ( cql3 ) { result = cassandra . execute_cql3_query ( query , useCompression ? Compression . GZIP : Compression . NONE , ThriftConverter . consistencyLevel ( getConsistency ( ) ) ) ; } else { result = cassandra . execute_cql_query ( query , useCompression ? Compression . GZIP : Compression . NONE ) ; } if ( log . isDebugEnabled ( ) ) { log . debug ( "Found CqlResult: {}" , result ) ; } switch ( result . getType ( ) ) { case VOID : rows = new CqlRows < K , N , V > ( ) ; break ; default : if ( result . getRowsSize ( ) > 0 ) { LinkedHashMap < ByteBuffer , List < Column > > ret = new LinkedHashMap < ByteBuffer , List < Column > > ( result . getRowsSize ( ) ) ; int keyColumnIndex = - 1 ; for ( Iterator < CqlRow > rowsIter = result . getRowsIterator ( ) ; rowsIter . hasNext ( ) ; ) { CqlRow row = rowsIter . next ( ) ; ByteBuffer kbb = ByteBuffer . wrap ( row . getKey ( ) ) ; // if CQL3 is used row.getKey() always returns null, so we have // to find the KEY in the columns. if ( cql3 ) { List < Column > rowcolumns = row . getColumns ( ) ; // first time through we find the column and then use the // column index to avoid needless work. if ( keyColumnIndex == - 1 ) { for ( Column c : rowcolumns ) { keyColumnIndex ++ ; String name = StringSerializer . get ( ) . fromBytes ( c . getName ( ) ) ; if ( name . toUpperCase ( ) . equals ( "KEY" ) ) { kbb = ByteBuffer . wrap ( c . getValue ( ) ) ; break ; } } } else { kbb = ByteBuffer . wrap ( row . getColumns ( ) . get ( keyColumnIndex ) . getValue ( ) ) ; } } ret . put ( kbb , filterKeyColumn ( row ) ) ; } Map < K , List < Column > > thriftRet = keySerializer . fromBytesMap ( ret ) ; rows = new CqlRows < K , N , V > ( ( LinkedHashMap < K , List < Column > > ) thriftRet , columnNameSerializer , valueSerializer ) ; } break ; } } catch ( Exception ex ) { throw keyspace . getExceptionsTranslator ( ) . translate ( ex ) ; } return rows ; } } ) , this ) ; }
For future releases we should consider refactoring how execute method converts the thrift CqlResult to Hector CqlRows . Starting with CQL3 the KEY is no longer returned by default and is no longer treated as a special thing . To get the KEY from the resultset we have to look at the columns . Using the KEY in CqlRows is nice and makes it easy to get results by the KEY . The downside is that users have to explicitly include the KEY in the statement . Changing how CqlRows work might break some existing use cases . For now the implementation finds the column and expects the statement to have the KEY .