Return-Path: X-Original-To: apmail-cassandra-commits-archive@www.apache.org Delivered-To: apmail-cassandra-commits-archive@www.apache.org Received: from mail.apache.org (hermes.apache.org [140.211.11.3]) by minotaur.apache.org (Postfix) with SMTP id C354017D36 for ; Wed, 27 May 2015 18:52:56 +0000 (UTC) Received: (qmail 95815 invoked by uid 500); 27 May 2015 18:52:53 -0000 Delivered-To: apmail-cassandra-commits-archive@cassandra.apache.org Received: (qmail 95758 invoked by uid 500); 27 May 2015 18:52:53 -0000 Mailing-List: contact commits-help@cassandra.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: dev@cassandra.apache.org Delivered-To: mailing list commits@cassandra.apache.org Received: (qmail 95451 invoked by uid 99); 27 May 2015 18:52:53 -0000 Received: from git1-us-west.apache.org (HELO git1-us-west.apache.org) (140.211.11.23) by apache.org (qpsmtpd/0.29) with ESMTP; Wed, 27 May 2015 18:52:53 +0000 Received: by git1-us-west.apache.org (ASF Mail Server at git1-us-west.apache.org, from userid 33) id 2C5A7DFFF0; Wed, 27 May 2015 18:52:53 +0000 (UTC) Content-Type: text/plain; charset="us-ascii" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit From: tylerhobbs@apache.org To: commits@cassandra.apache.org Date: Wed, 27 May 2015 18:52:53 -0000 Message-Id: <364aaae0dc7f498ba6fa0fdda7d26b51@git.apache.org> X-Mailer: ASF-Git Admin Mailer Subject: [1/5] cassandra git commit: Fix error executing bound statement after adding a collection Repository: cassandra Updated Branches: refs/heads/cassandra-2.2 f9c998cbc -> 80ba11c62 Fix error executing bound statement after adding a collection patch by blerer; reviewed by slebresne for CASSANDRA-9411 Project: http://git-wip-us.apache.org/repos/asf/cassandra/repo Commit: http://git-wip-us.apache.org/repos/asf/cassandra/commit/63165a71 Tree: http://git-wip-us.apache.org/repos/asf/cassandra/tree/63165a71 Diff: http://git-wip-us.apache.org/repos/asf/cassandra/diff/63165a71 Branch: refs/heads/cassandra-2.2 Commit: 63165a719cd8ec9d7f06c186f61d39403e192edc Parents: 3e4ed96 Author: Benjamin Lerer Authored: Wed May 27 16:00:52 2015 +0200 Committer: Sylvain Lebresne Committed: Wed May 27 16:00:52 2015 +0200 ---------------------------------------------------------------------- CHANGES.txt | 1 + .../cql3/statements/ModificationStatement.java | 6 +- .../cql3/statements/SelectStatement.java | 186 +++++++++++-------- 3 files changed, 110 insertions(+), 83 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/cassandra/blob/63165a71/CHANGES.txt ---------------------------------------------------------------------- diff --git a/CHANGES.txt b/CHANGES.txt index af08802..709100b 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -1,4 +1,5 @@ 2.0.16: + * Fix failing bound statement after adding a collection (CASSANDRA-9411) * Fix counting cache serialization in request metrics (CASSANDRA-9466) * (cqlsh) Add LOGIN command to switch users (CASSANDRA-7212) * Clone SliceQueryFilter in AbstractReadCommand implementations (CASSANDRA-8940) http://git-wip-us.apache.org/repos/asf/cassandra/blob/63165a71/src/java/org/apache/cassandra/cql3/statements/ModificationStatement.java ---------------------------------------------------------------------- diff --git a/src/java/org/apache/cassandra/cql3/statements/ModificationStatement.java b/src/java/org/apache/cassandra/cql3/statements/ModificationStatement.java index db22e7d..3852920 100644 --- a/src/java/org/apache/cassandra/cql3/statements/ModificationStatement.java +++ b/src/java/org/apache/cassandra/cql3/statements/ModificationStatement.java @@ -668,7 +668,8 @@ public abstract class ModificationStatement implements CQLStatement, MeasurableF private static ResultSet buildCasFailureResultSet(ByteBuffer key, ColumnFamily cf, Iterable columnsWithConditions, boolean isBatch) throws InvalidRequestException { - CFDefinition cfDef = cf.metadata().getCfDef(); + CFMetaData cfm = cf.metadata(); + CFDefinition cfDef = cfm.getCfDef(); Selection selection; if (columnsWithConditions == null) @@ -694,7 +695,8 @@ public abstract class ModificationStatement implements CQLStatement, MeasurableF long now = System.currentTimeMillis(); Selection.ResultSetBuilder builder = selection.resultSetBuilder(now); - SelectStatement.forSelection(cfDef, selection).processColumnFamily(key, cf, Collections.emptyList(), now, builder); + SelectStatement.forSelection(cfm, selection) + .processColumnFamily(cfDef, key, cf, Collections.emptyList(), now, builder); return builder.build(); } http://git-wip-us.apache.org/repos/asf/cassandra/blob/63165a71/src/java/org/apache/cassandra/cql3/statements/SelectStatement.java ---------------------------------------------------------------------- diff --git a/src/java/org/apache/cassandra/cql3/statements/SelectStatement.java b/src/java/org/apache/cassandra/cql3/statements/SelectStatement.java index 8a4deb6..95e0441 100644 --- a/src/java/org/apache/cassandra/cql3/statements/SelectStatement.java +++ b/src/java/org/apache/cassandra/cql3/statements/SelectStatement.java @@ -46,6 +46,7 @@ import org.apache.cassandra.service.StorageProxy; import org.apache.cassandra.service.StorageService; import org.apache.cassandra.service.pager.*; import org.apache.cassandra.db.ConsistencyLevel; +import org.apache.cassandra.thrift.ColumnDef; import org.apache.cassandra.thrift.IndexExpression; import org.apache.cassandra.thrift.IndexOperator; import org.apache.cassandra.thrift.ThriftValidation; @@ -68,7 +69,7 @@ public class SelectStatement implements CQLStatement, MeasurableForPreparedCache private static final int DEFAULT_COUNT_PAGE_SIZE = 10000; private final int boundTerms; - public final CFDefinition cfDef; + public final CFMetaData cfm; public final Parameters parameters; private final Selection selection; private final Term limit; @@ -110,13 +111,13 @@ public class SelectStatement implements CQLStatement, MeasurableForPreparedCache } }; - public SelectStatement(CFDefinition cfDef, int boundTerms, Parameters parameters, Selection selection, Term limit) + public SelectStatement(CFMetaData cfm, int boundTerms, Parameters parameters, Selection selection, Term limit) { - this.cfDef = cfDef; + this.cfm = cfm; this.boundTerms = boundTerms; this.selection = selection; - this.keyRestrictions = new Restriction[cfDef.partitionKeyCount()]; - this.columnRestrictions = new Restriction[cfDef.clusteringColumnsCount()]; + this.keyRestrictions = new Restriction[cfm.partitionKeyColumns().size()]; + this.columnRestrictions = new Restriction[cfm.clusteringKeyColumns().size()]; this.parameters = parameters; this.limit = limit; @@ -126,7 +127,7 @@ public class SelectStatement implements CQLStatement, MeasurableForPreparedCache private void initStaticColumnsInfo() { - if (!cfDef.cfm.hasStaticColumns()) + if (!cfm.hasStaticColumns()) return; // If it's a wildcard, we do select static but not only them @@ -152,9 +153,9 @@ public class SelectStatement implements CQLStatement, MeasurableForPreparedCache // Creates a simple select based on the given selection. // Note that the results select statement should not be used for actual queries, but only for processing already // queried data through processColumnFamily. - static SelectStatement forSelection(CFDefinition cfDef, Selection selection) + static SelectStatement forSelection(CFMetaData cfm, Selection selection) { - return new SelectStatement(cfDef, 0, defaultParameters, selection, null); + return new SelectStatement(cfm, 0, defaultParameters, selection, null); } public ResultSet.Metadata getResultMetadata() @@ -195,6 +196,7 @@ public class SelectStatement implements CQLStatement, MeasurableForPreparedCache public ResultMessage.Rows execute(QueryState state, QueryOptions options) throws RequestExecutionException, RequestValidationException { + CFDefinition cfDef = cfm.getCfDef(); ConsistencyLevel cl = options.getConsistency(); List variables = options.getValues(); if (cl == null) @@ -208,11 +210,11 @@ public class SelectStatement implements CQLStatement, MeasurableForPreparedCache Pageable command; if (isKeyRange || usesSecondaryIndexing) { - command = getRangeCommand(variables, limitForQuery, now); + command = getRangeCommand(cfDef, variables, limitForQuery, now); } else { - List commands = getSliceCommands(variables, limitForQuery, now); + List commands = getSliceCommands(cfDef, variables, limitForQuery, now); command = commands == null ? null : new Pageable.ReadCommands(commands, limitForQuery); } @@ -225,13 +227,13 @@ public class SelectStatement implements CQLStatement, MeasurableForPreparedCache if (pageSize <= 0 || command == null || !QueryPagers.mayNeedPaging(command, pageSize)) { - return execute(command, cl, variables, limit, now); + return execute(cfDef, command, cl, variables, limit, now); } else { QueryPager pager = QueryPagers.pager(command, cl, options.getPagingState()); if (parameters.isCount) - return pageCountQuery(pager, variables, pageSize, now, limit); + return pageCountQuery(cfDef, pager, variables, pageSize, now, limit); // We can't properly do post-query ordering if we page (see #6722) if (needsPostQueryOrdering()) @@ -239,14 +241,19 @@ public class SelectStatement implements CQLStatement, MeasurableForPreparedCache + "ORDER BY or the IN and sort client side, or disable paging for this query"); List page = pager.fetchPage(pageSize); - ResultMessage.Rows msg = processResults(page, variables, limit, now); + ResultMessage.Rows msg = processResults(cfDef, page, variables, limit, now); if (!pager.isExhausted()) msg.result.metadata.setHasMorePages(pager.state()); return msg; } } - private ResultMessage.Rows execute(Pageable command, ConsistencyLevel cl, List variables, int limit, long now) throws RequestValidationException, RequestExecutionException + private ResultMessage.Rows execute(CFDefinition cfDef, + Pageable command, + ConsistencyLevel cl, + List variables, + int limit, + long now) throws RequestValidationException, RequestExecutionException { List rows; if (command == null) @@ -260,17 +267,22 @@ public class SelectStatement implements CQLStatement, MeasurableForPreparedCache : StorageProxy.getRangeSlice((RangeSliceCommand)command, cl); } - return processResults(rows, variables, limit, now); + return processResults(cfDef, rows, variables, limit, now); } - private ResultMessage.Rows pageCountQuery(QueryPager pager, List variables, int pageSize, long now, int limit) throws RequestValidationException, RequestExecutionException + private ResultMessage.Rows pageCountQuery(CFDefinition cfDef, + QueryPager pager, + List variables, + int pageSize, + long now, + int limit) throws RequestValidationException, RequestExecutionException { int count = 0; while (!pager.isExhausted()) { int maxLimit = pager.maxRemaining(); logger.debug("New maxLimit for paged count query is {}", maxLimit); - ResultSet rset = process(pager.fetchPage(pageSize), variables, maxLimit, now); + ResultSet rset = process(cfDef, pager.fetchPage(pageSize), variables, maxLimit, now); count += rset.rows.size(); } @@ -280,10 +292,10 @@ public class SelectStatement implements CQLStatement, MeasurableForPreparedCache return new ResultMessage.Rows(result); } - public ResultMessage.Rows processResults(List rows, List variables, int limit, long now) throws RequestValidationException + public ResultMessage.Rows processResults(CFDefinition cfDef, List rows, List variables, int limit, long now) throws RequestValidationException { // Even for count, we need to process the result as it'll group some column together in sparse column families - ResultSet rset = process(rows, variables, limit, now); + ResultSet rset = process(cfDef, rows, variables, limit, now); rset = parameters.isCount ? rset.makeCountResult(parameters.countAlias) : rset; return new ResultMessage.Rows(rset); } @@ -299,6 +311,7 @@ public class SelectStatement implements CQLStatement, MeasurableForPreparedCache public ResultMessage.Rows executeInternal(QueryState state, QueryOptions options) throws RequestExecutionException, RequestValidationException { + CFDefinition cfDef = cfm.getCfDef(); List variables = options.getValues(); int limit = getLimit(variables); int limitForQuery = updateLimitForQuery(limit); @@ -306,43 +319,47 @@ public class SelectStatement implements CQLStatement, MeasurableForPreparedCache List rows; if (isKeyRange || usesSecondaryIndexing) { - RangeSliceCommand command = getRangeCommand(variables, limitForQuery, now); + RangeSliceCommand command = getRangeCommand(cfDef, variables, limitForQuery, now); rows = command == null ? Collections.emptyList() : command.executeLocally(); } else { - List commands = getSliceCommands(variables, limitForQuery, now); + List commands = getSliceCommands(cfDef, variables, limitForQuery, now); rows = commands == null ? Collections.emptyList() : readLocally(keyspace(), commands); } - return processResults(rows, variables, limit, now); + return processResults(cfDef, rows, variables, limit, now); } public ResultSet process(List rows) throws InvalidRequestException { assert !parameters.isCount; // not yet needed - return process(rows, Collections.emptyList(), getLimit(Collections.emptyList()), System.currentTimeMillis()); + return process(cfm.getCfDef(), + rows, + Collections.emptyList(), + getLimit(Collections.emptyList()), + System.currentTimeMillis()); } public String keyspace() { - return cfDef.cfm.ksName; + return cfm.ksName; } public String columnFamily() { - return cfDef.cfm.cfName; + return cfm.cfName; } - private List getSliceCommands(List variables, int limit, long now) throws RequestValidationException + private List getSliceCommands(CFDefinition cfDef, List variables, int limit, long now) throws RequestValidationException { - Collection keys = getKeys(variables); + Collection keys = getKeys(cfDef, variables); if (keys.isEmpty()) // in case of IN () for (the last column of) the partition key. return null; List commands = new ArrayList<>(keys.size()); - IDiskAtomFilter filter = makeFilter(variables, limit); + IDiskAtomFilter filter = makeFilter(cfDef, variables, limit); if (filter == null) return null; @@ -360,22 +377,22 @@ public class SelectStatement implements CQLStatement, MeasurableForPreparedCache return commands; } - private RangeSliceCommand getRangeCommand(List variables, int limit, long now) throws RequestValidationException + private RangeSliceCommand getRangeCommand(CFDefinition cfDef, List variables, int limit, long now) throws RequestValidationException { - IDiskAtomFilter filter = makeFilter(variables, limit); + IDiskAtomFilter filter = makeFilter(cfDef, variables, limit); if (filter == null) return null; List expressions = getIndexExpressions(variables); // The LIMIT provided by the user is the number of CQL row he wants returned. // We want to have getRangeSlice to count the number of columns, not the number of keys. - AbstractBounds keyBounds = getKeyBounds(variables); + AbstractBounds keyBounds = getKeyBounds(cfDef, variables); return keyBounds == null ? null : new RangeSliceCommand(keyspace(), columnFamily(), now, filter, keyBounds, expressions, limit, !parameters.isDistinct, false); } - private AbstractBounds getKeyBounds(List variables) throws InvalidRequestException + private AbstractBounds getKeyBounds(CFDefinition cfDef, List variables) throws InvalidRequestException { IPartitioner p = StorageService.getPartitioner(); @@ -408,8 +425,8 @@ public class SelectStatement implements CQLStatement, MeasurableForPreparedCache } else { - ByteBuffer startKeyBytes = getKeyBound(Bound.START, variables); - ByteBuffer finishKeyBytes = getKeyBound(Bound.END, variables); + ByteBuffer startKeyBytes = getKeyBound(cfDef, Bound.START, variables); + ByteBuffer finishKeyBytes = getKeyBound(cfDef, Bound.END, variables); RowPosition startKey = RowPosition.forKey(startKeyBytes, p); RowPosition finishKey = RowPosition.forKey(finishKeyBytes, p); @@ -434,7 +451,7 @@ public class SelectStatement implements CQLStatement, MeasurableForPreparedCache private ColumnSlice makeStaticSlice() { - ColumnNameBuilder staticPrefix = cfDef.cfm.getStaticColumnNameBuilder(); + ColumnNameBuilder staticPrefix = cfm.getStaticColumnNameBuilder(); // Note: we could use staticPrefix.build() for the start bound, but EMPTY_BYTE_BUFFER gives us the // same effect while saving a few CPU cycles. return isReversed @@ -442,7 +459,7 @@ public class SelectStatement implements CQLStatement, MeasurableForPreparedCache : new ColumnSlice(ByteBufferUtil.EMPTY_BYTE_BUFFER, staticPrefix.buildAsEndOfRange()); } - private IDiskAtomFilter makeFilter(List variables, int limit) + private IDiskAtomFilter makeFilter(CFDefinition cfDef, List variables, int limit) throws InvalidRequestException { int toGroup = cfDef.isCompact ? -1 : cfDef.clusteringColumnsCount(); @@ -457,14 +474,14 @@ public class SelectStatement implements CQLStatement, MeasurableForPreparedCache toGroup = selectsStaticColumns ? toGroup : SliceQueryFilter.IGNORE_TOMBSTONED_PARTITIONS; return new SliceQueryFilter(ColumnSlice.ALL_COLUMNS_ARRAY, false, 1, toGroup); } - else if (isColumnRange()) + else if (isColumnRange(cfDef)) { // For sparse, we used to ask for 'defined columns' * 'asked limit' (where defined columns includes the row marker) // to account for the grouping of columns. // Since that doesn't work for maps/sets/lists, we now use the compositesToGroup option of SliceQueryFilter. // But we must preserve backward compatibility too (for mixed version cluster that is). - List startBounds = getRequestedBound(Bound.START, variables); - List endBounds = getRequestedBound(Bound.END, variables); + List startBounds = getRequestedBound(cfDef, Bound.START, variables); + List endBounds = getRequestedBound(cfDef, Bound.END, variables); assert startBounds.size() == endBounds.size(); // Handles fetching static columns. Note that for 2i, the filter is just used to restrict @@ -478,18 +495,18 @@ public class SelectStatement implements CQLStatement, MeasurableForPreparedCache if (startBounds.size() == 1) { ColumnSlice slice = new ColumnSlice(startBounds.get(0), endBounds.get(0)); - if (slice.isAlwaysEmpty(cfDef.cfm.comparator, isReversed)) + if (slice.isAlwaysEmpty(cfm.comparator, isReversed)) return staticSlice == null ? null : sliceFilter(staticSlice, limit, toGroup); if (staticSlice == null) return sliceFilter(slice, limit, toGroup); if (isReversed) - return slice.includes(cfDef.cfm.comparator.reverseComparator, staticSlice.start) + return slice.includes(cfm.comparator.reverseComparator, staticSlice.start) ? sliceFilter(new ColumnSlice(slice.start, staticSlice.finish), limit, toGroup) : sliceFilter(new ColumnSlice[]{ slice, staticSlice }, limit, toGroup); else - return slice.includes(cfDef.cfm.comparator, staticSlice.finish) + return slice.includes(cfm.comparator, staticSlice.finish) ? sliceFilter(new ColumnSlice(staticSlice.start, slice.finish), limit, toGroup) : sliceFilter(new ColumnSlice[]{ staticSlice, slice }, limit, toGroup); } @@ -498,7 +515,7 @@ public class SelectStatement implements CQLStatement, MeasurableForPreparedCache for (int i = 0; i < startBounds.size(); i++) { ColumnSlice slice = new ColumnSlice(startBounds.get(i), endBounds.get(i)); - if (!slice.isAlwaysEmpty(cfDef.cfm.comparator, isReversed)) + if (!slice.isAlwaysEmpty(cfm.comparator, isReversed)) l.add(slice); } @@ -513,7 +530,7 @@ public class SelectStatement implements CQLStatement, MeasurableForPreparedCache ColumnSlice[] slices; if (isReversed) { - if (l.get(l.size() - 1).includes(cfDef.cfm.comparator.reverseComparator, staticSlice.start)) + if (l.get(l.size() - 1).includes(cfm.comparator.reverseComparator, staticSlice.start)) { slices = l.toArray(new ColumnSlice[l.size()]); slices[slices.length-1] = new ColumnSlice(slices[slices.length-1].start, ByteBufferUtil.EMPTY_BYTE_BUFFER); @@ -526,7 +543,7 @@ public class SelectStatement implements CQLStatement, MeasurableForPreparedCache } else { - if (l.get(0).includes(cfDef.cfm.comparator, staticSlice.finish)) + if (l.get(0).includes(cfm.comparator, staticSlice.finish)) { slices = new ColumnSlice[l.size()]; slices[0] = new ColumnSlice(ByteBufferUtil.EMPTY_BYTE_BUFFER, l.get(0).finish); @@ -545,7 +562,7 @@ public class SelectStatement implements CQLStatement, MeasurableForPreparedCache } else { - SortedSet cellNames = getRequestedColumns(variables); + SortedSet cellNames = getRequestedColumns(cfDef, variables); if (cellNames == null) // in case of IN () for the last column of the key return null; QueryProcessor.validateCellNames(cellNames); @@ -598,7 +615,7 @@ public class SelectStatement implements CQLStatement, MeasurableForPreparedCache : limit; } - private Collection getKeys(final List variables) throws InvalidRequestException + private Collection getKeys(CFDefinition cfDef, List variables) throws InvalidRequestException { List keys = new ArrayList(); ColumnNameBuilder builder = cfDef.getKeyNameBuilder(); @@ -632,7 +649,7 @@ public class SelectStatement implements CQLStatement, MeasurableForPreparedCache return keys; } - private ByteBuffer getKeyBound(Bound b, List variables) throws InvalidRequestException + private ByteBuffer getKeyBound(CFDefinition cfDef, Bound b, List variables) throws InvalidRequestException { // Deal with unrestricted partition key components (special-casing is required to deal with 2i queries on the first // component of a composite partition key). @@ -694,7 +711,7 @@ public class SelectStatement implements CQLStatement, MeasurableForPreparedCache return true; } - private boolean isColumnRange() + private boolean isColumnRange(CFDefinition cfDef) { // Due to CASSANDRA-5762, we always do a slice for CQL3 tables (not compact, composite). // Static CF (non compact but non composite) never entails a column slice however @@ -711,11 +728,11 @@ public class SelectStatement implements CQLStatement, MeasurableForPreparedCache return false; } - private SortedSet getRequestedColumns(List variables) throws InvalidRequestException + private SortedSet getRequestedColumns(CFDefinition cfDef, List variables) throws InvalidRequestException { // Note: getRequestedColumns don't handle static columns, but due to CASSANDRA-5762 // we always do a slice for CQL3 tables, so it's ok to ignore them here - assert !isColumnRange(); + assert !isColumnRange(cfDef); ColumnNameBuilder builder = cfDef.getColumnNameBuilder(); Iterator idIter = cfDef.clusteringColumns().iterator(); @@ -771,7 +788,7 @@ public class SelectStatement implements CQLStatement, MeasurableForPreparedCache if (cfDef.isCompact) columns.add(b.build()); else - columns.addAll(addSelectedColumns(b)); + columns.addAll(addSelectedColumns(cfDef, b)); } return columns; } @@ -797,35 +814,35 @@ public class SelectStatement implements CQLStatement, MeasurableForPreparedCache if (cfDef.isCompact) inValues.add(b.build()); else - inValues.addAll(addSelectedColumns(b)); + inValues.addAll(addSelectedColumns(cfDef, b)); } return inValues; } } } - return addSelectedColumns(builder); + return addSelectedColumns(cfDef, builder); } - private SortedSet addSelectedColumns(ColumnNameBuilder builder) + private SortedSet addSelectedColumns(CFDefinition cfDef, ColumnNameBuilder builder) { if (cfDef.isCompact) { - return FBUtilities.singleton(builder.build(), cfDef.cfm.comparator); + return FBUtilities.singleton(builder.build(), cfm.comparator); } else { // Collections require doing a slice query because a given collection is a // non-know set of columns, so we shouldn't get there - assert !selectACollection(); + assert !selectACollection(cfDef); - SortedSet columns = new TreeSet(cfDef.cfm.comparator); + SortedSet columns = new TreeSet(cfm.comparator); // We need to query the selected column as well as the marker // column (for the case where the row exists but has no columns outside the PK) // Two exceptions are "static CF" (non-composite non-compact CF) and "super CF" // that don't have marker and for which we must query all columns instead - if (cfDef.isComposite && !cfDef.cfm.isSuper()) + if (cfDef.isComposite && !cfm.isSuper()) { // marker columns.add(builder.copy().add(ByteBufferUtil.EMPTY_BYTE_BUFFER).build()); @@ -850,7 +867,7 @@ public class SelectStatement implements CQLStatement, MeasurableForPreparedCache } } - private boolean selectACollection() + private boolean selectACollection(CFDefinition cfDef) { if (!cfDef.hasCollections) return false; @@ -1036,9 +1053,11 @@ public class SelectStatement implements CQLStatement, MeasurableForPreparedCache return slice.bound(b, variables); } - private List getRequestedBound(Bound b, List variables) throws InvalidRequestException + private List getRequestedBound(CFDefinition cfDef, + Bound b, + List variables) throws InvalidRequestException { - assert isColumnRange(); + assert isColumnRange(cfDef); return buildBound(b, new ArrayList(cfDef.clusteringColumns()), columnRestrictions, @@ -1137,7 +1156,8 @@ public class SelectStatement implements CQLStatement, MeasurableForPreparedCache } } - private ResultSet process(List rows, List variables, int limit, long now) throws InvalidRequestException + private ResultSet process(CFDefinition cfDef, List rows, List variables, int limit, long now) + throws InvalidRequestException { Selection.ResultSetBuilder result = selection.resultSetBuilder(now); for (org.apache.cassandra.db.Row row : rows) @@ -1146,12 +1166,12 @@ public class SelectStatement implements CQLStatement, MeasurableForPreparedCache if (row.cf == null) continue; - processColumnFamily(row.key.key, row.cf, variables, now, result); + processColumnFamily(cfDef, row.key.key, row.cf, variables, now, result); } ResultSet cqlRows = result.build(); - orderResults(cqlRows); + orderResults(cfDef, cqlRows); // Internal calls always return columns in the comparator order, even when reverse was set if (isReversed) @@ -1163,11 +1183,15 @@ public class SelectStatement implements CQLStatement, MeasurableForPreparedCache } // Used by ModificationStatement for CAS operations - void processColumnFamily(ByteBuffer key, ColumnFamily cf, List variables, long now, Selection.ResultSetBuilder result) - throws InvalidRequestException + void processColumnFamily(CFDefinition cfDef, + ByteBuffer key, + ColumnFamily cf, + List variables, + long now, + Selection.ResultSetBuilder result) throws InvalidRequestException { ByteBuffer[] keyComponents = cfDef.hasCompositeKey - ? ((CompositeType)cfDef.cfm.getKeyValidator()).split(key) + ? ((CompositeType) cfm.getKeyValidator()).split(key) : new ByteBuffer[]{ key }; if (parameters.isDistinct && !selectsStaticColumns) @@ -1191,11 +1215,11 @@ public class SelectStatement implements CQLStatement, MeasurableForPreparedCache ByteBuffer[] components = null; if (cfDef.isComposite) { - components = ((CompositeType)cfDef.cfm.comparator).split(c.name()); + components = ((CompositeType) cfm.comparator).split(c.name()); } else if (sliceRestriction != null) { - Comparator comp = cfDef.cfm.comparator; + Comparator comp = cfm.comparator; // For dynamic CF, the column could be out of the requested bounds, filter here if (!sliceRestriction.isInclusive(Bound.START)) @@ -1251,7 +1275,7 @@ public class SelectStatement implements CQLStatement, MeasurableForPreparedCache else if (cfDef.isComposite) { // Sparse case: group column in cqlRow when composite prefix is equal - CompositeType composite = (CompositeType)cfDef.cfm.comparator; + CompositeType composite = (CompositeType) cfm.comparator; ColumnGroupMap.Builder builder = new ColumnGroupMap.Builder(composite, cfDef.hasCollections, now); @@ -1325,7 +1349,7 @@ public class SelectStatement implements CQLStatement, MeasurableForPreparedCache /** * Orders results when multiple keys are selected (using IN) */ - private void orderResults(ResultSet cqlRows) + private void orderResults(CFDefinition cfDef, ResultSet cqlRows) { if (cqlRows.size() == 0 || !needsPostQueryOrdering()) return; @@ -1336,7 +1360,7 @@ public class SelectStatement implements CQLStatement, MeasurableForPreparedCache // because there is no point of using composite comparator if there is only one order condition if (parameters.orderings.size() == 1) { - CFDefinition.Name ordering = cfDef.get(parameters.orderings.keySet().iterator().next().prepare(cfDef.cfm)); + CFDefinition.Name ordering = cfDef.get(parameters.orderings.keySet().iterator().next().prepare(cfm)); Collections.sort(cqlRows.rows, new SingleColumnComparator(orderingIndexes.get(ordering), ordering.type)); return; } @@ -1430,7 +1454,7 @@ public class SelectStatement implements CQLStatement, MeasurableForPreparedCache return false; } - private void validateDistinctSelection() + private void validateDistinctSelection(CFDefinition cfDef) throws InvalidRequestException { Collection requestedColumns = selection.getColumns(); @@ -1460,7 +1484,7 @@ public class SelectStatement implements CQLStatement, MeasurableForPreparedCache private final List whereClause; private final Term.Raw limit; - public RawStatement(CFName cfName, Parameters parameters, List selectClause, List whereClause, Term.Raw limit) + public RawStatement(CFName cfName,Parameters parameters, List selectClause, List whereClause, Term.Raw limit) { super(cfName); this.parameters = parameters; @@ -1485,7 +1509,7 @@ public class SelectStatement implements CQLStatement, MeasurableForPreparedCache ? Selection.wildcard(cfDef) : Selection.fromSelectors(cfDef, selectClause); - SelectStatement stmt = new SelectStatement(cfDef, boundNames.size(), parameters, selection, prepareLimit(boundNames)); + SelectStatement stmt = new SelectStatement(cfm, boundNames.size(), parameters, selection, prepareLimit(boundNames)); /* * WHERE clause. For a given entity, rules are: @@ -1570,10 +1594,10 @@ public class SelectStatement implements CQLStatement, MeasurableForPreparedCache if (!stmt.parameters.orderings.isEmpty()) processOrderingClause(stmt, cfDef); - checkNeedsFiltering(stmt); + checkNeedsFiltering(stmt, cfDef); if (parameters.isDistinct) - stmt.validateDistinctSelection(); + stmt.validateDistinctSelection(cfDef); return new ParsedStatement.Prepared(stmt, boundNames); } @@ -2054,7 +2078,7 @@ public class SelectStatement implements CQLStatement, MeasurableForPreparedCache { if (!restriction.isMultiColumn() && i != stmt.columnRestrictions.length - 1) throw new InvalidRequestException(String.format("Clustering column \"%s\" cannot be restricted by an IN relation", cname)); - if (stmt.selectACollection()) + if (stmt.selectACollection(cfDef)) throw new InvalidRequestException(String.format("Cannot restrict column \"%s\" by IN relation as a collection is selected by the query", cname)); if (restriction.isMultiColumn()) @@ -2187,7 +2211,7 @@ public class SelectStatement implements CQLStatement, MeasurableForPreparedCache } /** If ALLOW FILTERING was not specified, this verifies that it is not needed */ - private void checkNeedsFiltering(SelectStatement stmt) throws InvalidRequestException + private void checkNeedsFiltering(SelectStatement stmt, CFDefinition cfDef) throws InvalidRequestException { // non-key-range non-indexed queries cannot involve filtering underneath if (!parameters.allowFiltering && (stmt.isKeyRange || stmt.usesSecondaryIndexing)) @@ -2213,7 +2237,7 @@ public class SelectStatement implements CQLStatement, MeasurableForPreparedCache // than answering with something that is wrong. if (stmt.sliceRestriction != null && stmt.isKeyRange && limit != null) { - SingleColumnRelation rel = findInclusiveClusteringRelationForCompact(stmt.cfDef); + SingleColumnRelation rel = findInclusiveClusteringRelationForCompact(cfDef); throw new InvalidRequestException(String.format("The query requests a restriction of rows with a strict bound (%s) over a range of partitions. " + "This is not supported by the underlying storage engine for COMPACT tables if a LIMIT is provided. " + "Please either make the condition non strict (%s) or remove the user LIMIT", rel, rel.withNonStrictOperator()));