diff --git a/concourse-server/src/main/java/com/cinchapi/concourse/server/ops/Strategy.java b/concourse-server/src/main/java/com/cinchapi/concourse/server/ops/Strategy.java index 4852e3289..27aa11046 100644 --- a/concourse-server/src/main/java/com/cinchapi/concourse/server/ops/Strategy.java +++ b/concourse-server/src/main/java/com/cinchapi/concourse/server/ops/Strategy.java @@ -71,22 +71,23 @@ public Source source(String key, long record) { .keysRequiringTimestampRetrieval().containsKey(key) || (isOrderKey && isHistoricalOperation); Source source; - if((isConditionKey || isOrderKey) && !isKeyRequiringTimestampRetrieval - && command.operationRecords().size() != 1) { - // The IndexRecord must be loaded to evaluate the condition, so - // leverage it to gather the values for key/record - source = Source.INDEX; + if(memory.contains(record)) { + source = Source.RECORD; + } + else if(memory.contains(key, record)) { + source = Source.FIELD; } else if(isWideOperation) { // The entire record is involved in the operation, so force the full // TableRecord to be loaded. source = Source.RECORD; } - else if(memory.contains(record)) { - source = Source.RECORD; - } - else if(memory.contains(key, record)) { - source = Source.FIELD; + else if((isConditionKey || isOrderKey) + && !isKeyRequiringTimestampRetrieval + && command.operationRecords().size() != 1) { + // The IndexRecord must be loaded to evaluate the condition, so + // leverage it to gather the values for key/record + source = Source.INDEX; } else { source = command.operationKeys().size() > 1 ? Source.RECORD diff --git a/concourse-server/src/test/java/com/cinchapi/concourse/server/ops/StrategyTest.java b/concourse-server/src/test/java/com/cinchapi/concourse/server/ops/StrategyTest.java new file mode 100644 index 000000000..5557cd9ec --- /dev/null +++ b/concourse-server/src/test/java/com/cinchapi/concourse/server/ops/StrategyTest.java @@ -0,0 +1,70 @@ +/* + * Copyright (c) 2013-2025 Cinchapi Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.cinchapi.concourse.server.ops; + +import java.lang.reflect.Method; +import java.util.List; + +import org.junit.Test; + +import com.cinchapi.common.reflect.Reflection; +import com.cinchapi.concourse.lang.Criteria; +import com.cinchapi.concourse.lang.Language; +import com.cinchapi.concourse.server.ConcourseServer; +import com.cinchapi.concourse.server.ops.Strategy.Source; +import com.cinchapi.concourse.server.storage.temp.Queue; +import com.cinchapi.concourse.thrift.AccessToken; +import com.cinchapi.concourse.thrift.Operator; +import com.cinchapi.concourse.thrift.TCriteria; +import com.cinchapi.concourse.thrift.TransactionToken; +import com.google.common.collect.ImmutableList; + +/** + * Unit tests for the {@link Strategy} framework. + * + * @author Jeff Nelson + */ +public class StrategyTest { + + @Test + public void testNavigationConditionKeyUseIndexForLookup() { + // TODO: this also requires fixes to Command to include intermediate + // navigation stops within conditionKeys + Method method = Reflection.getMethodUnboxed(ConcourseServer.class, + "selectKeysCriteria", List.class, TCriteria.class, + AccessToken.class, TransactionToken.class, String.class); + List keys = ImmutableList.of("name", "credential.email"); + TCriteria criteria = Language.translateToThriftCriteria( + Criteria.where().key("credential.email") + .operator(Operator.EQUALS).value("test@test.com").and() + .key("_").operator(Operator.EQUALS).value("User")); + AccessToken creds = new AccessToken(); + TransactionToken transaction = new TransactionToken(); + String environment = ""; + Command command = new Command(method, keys, criteria, creds, + transaction, environment); + Strategy strategy = new Strategy(command, new Queue(1)); // TODO: will + // need to use + // a different + // store to + // test this + Source source = strategy.source("email", 1); + // FIXME: This is using RECORD because Queue's memory says everything is + // in memory + // Assert.assertEquals(Source.INDEX, source); + } + +}