@Override protected ResultObjectProvider executeQuery( Executor ex, ClassMetaData base, ClassMetaData[] types, boolean subclasses, ExpressionFactory[] facts, QueryExpressions[] parsed, Object[] params, Range range) { log.debug("In executeQuery"); IndexExpressionVisitor visitor = new IndexExpressionVisitor((CassandraClassMetaData) base, params); parsed[0].filter.acceptVisit(visitor); // the list of queries we need to execute List<IndexQuery> queries = visitor.getVisitors(); AbstractIndexOperation indexOp = getIndexOp( queries.get(0), parsed[0].ordering, parsed[0].ascending, (CassandraClassMetaData) base); ResultCompiler compiler = new ResultCompiler(indexOp.getComprator()); Keyspace keyspace = conf.getKeyspace(); compiler.addScanIterator(indexOp.scanIndex(queries.get(0), keyspace)); // loop throught and add all other clauses for (int i = 1; i < queries.size(); i++) { log.debug("indexOp: {} and base: {} with range: {}", new Object[] {indexOp, base, range}); compiler.addScanIterator(indexOp.scanIndex(queries.get(i), keyspace)); } int start = 0; int size = Integer.MAX_VALUE; if (range.start != 0 || range.end != Long.MAX_VALUE) { start = (int) range.start; size = (int) (range.end - range.start); // this is a limitation in cassandra paging, more than an int isn't supported for loading // columns. Not really an issue since that many rows propbably can't be loaded in ram anyway } // TODO T.N. incorporate LRS compiler.compile(start, size); CassandraResultObjectProvider results = new CassandraResultObjectProvider( compiler.getResults(), this.getContext().getStoreContext(), ctx.getFetchConfiguration(), (CassandraClassMetaData) base); return results; }
/** * Get the index for the query * * @param query * @return */ private AbstractIndexOperation getIndexOp( IndexQuery query, Value[] ordering, boolean[] orderAscending, CassandraClassMetaData metaData) { Collection<FieldExpression> expFields = query.getExpressions(); FieldOrder[] fields = new FieldOrder[expFields.size()]; IndexOrder[] orders = new IndexOrder[ordering.length]; Iterator<FieldExpression> expFieldsItr = expFields.iterator(); // all fields are ascending by default in field equality. for (int i = 0; i < fields.length; i++) { FieldExpression current = expFieldsItr.next(); // if there's not start but an end then this column must be // descending in // the index fields[i] = new FieldOrder(current.getField().getName(), true); log.debug("in getIndexOp with field: {}", fields[i]); } for (int i = 0; i < orders.length; i++) { orders[i] = new IndexOrder(((Path) ordering[i]).last().getName(), orderAscending[i]); } EntityFacade classMeta = conf.getMetaCache().getFacade(metaData, conf.getSerializer()); AbstractIndexOperation indexOp = classMeta.getIndexOperation(fields, orders); if (indexOp == null) { throw new UnsupportedException( String.format( "You attempted to query an index that does not exist. To perform this query you must define an index in the following format. '%s'", getIndexExpression(fields, orders))); } return indexOp; }