Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,10 @@
package org.apache.jackrabbit.oak.query;

import static java.util.Objects.requireNonNull;
import static org.apache.jackrabbit.JcrConstants.JCR_PRIMARYTYPE;
import static org.apache.jackrabbit.oak.plugins.index.IndexConstants.INDEX_DEFINITIONS_NAME;
import static org.apache.jackrabbit.oak.plugins.index.IndexConstants.INDEX_DEFINITIONS_NODE_TYPE;
import static org.apache.jackrabbit.oak.plugins.index.IndexConstants.REINDEX_PROPERTY_NAME;
import static org.apache.jackrabbit.oak.query.ast.AstElementFactory.copyElementAndCheckReference;

import java.math.BigInteger;
Expand All @@ -32,9 +36,11 @@
import java.util.stream.Collectors;

import org.apache.commons.lang3.StringUtils;
import org.apache.jackrabbit.oak.api.PropertyState;
import org.apache.jackrabbit.oak.api.PropertyValue;
import org.apache.jackrabbit.oak.api.Result.SizePrecision;
import org.apache.jackrabbit.oak.api.Tree;
import org.apache.jackrabbit.oak.api.Type;
import org.apache.jackrabbit.oak.namepath.JcrPathParser;
import org.apache.jackrabbit.oak.namepath.NamePathMapper;
import org.apache.jackrabbit.oak.plugins.index.IndexUtils;
Expand Down Expand Up @@ -1255,7 +1261,7 @@
}

@Override
public void verifyNotPotentiallySlow() {

Check failure on line 1264 in oak-core/src/main/java/org/apache/jackrabbit/oak/query/QueryImpl.java

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Refactor this method to reduce its Cognitive Complexity from 33 to the 15 allowed.

See more on https://sonarcloud.io/project/issues?id=org.apache.jackrabbit%3Ajackrabbit-oak&issues=AZrGjGzoLFjjD7KlGMvb&open=AZrGjGzoLFjjD7KlGMvb&pullRequest=2626
if (potentiallySlowTraversalQuery) {
QueryOptions.Traversal traversal = queryOptions.traversal;
if (traversal == Traversal.DEFAULT) {
Expand All @@ -1267,6 +1273,26 @@
}
String caller = IndexUtils.getCaller(settings.getIgnoredClassNamesInCallTrace());
String message = "Traversal query (query without index): " + statement + "; called by " + caller + "; consider creating an index";
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

would indeed be nice to refactor this slightly

if (traversal == Traversal.FAIL || traversal == Traversal.WARN && !potentiallySlowTraversalQueryLogged) {
HashSet<String> reindex = new HashSet<>();
Iterable<Tree> indexes = context.getRoot().getTree("/" + INDEX_DEFINITIONS_NAME).getChildren();
for (Tree index : indexes) {
String name = index.getName();
PropertyState primaryType = index.getProperty(JCR_PRIMARYTYPE);
if (primaryType != null && INDEX_DEFINITIONS_NODE_TYPE.equals(primaryType.getValue(Type.STRING))) {
PropertyState reindexProp = index.getProperty(REINDEX_PROPERTY_NAME);
if (reindexProp != null && reindexProp.getValue(Type.BOOLEAN)) {
reindex.add(name);
}
}
}
message += "\n\nExecution plan:\n" + getPlan();
if (!reindex.isEmpty()) {
String reindexNames = reindex.stream().map(name -> name + ",").collect(Collectors.joining());
message += "\n\nNote that the following indexes were unavailable because of re-indexing:\n"
+ reindexNames.substring(0, reindexNames.length() - 1);
}
}
switch (traversal) {
case DEFAULT:
// not possible (changed to either FAIL or WARN above)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,10 @@
*/
package org.apache.jackrabbit.oak.jcr.query;

import static org.apache.jackrabbit.oak.plugins.index.IndexConstants.INDEX_DEFINITIONS_NAME;
import static org.apache.jackrabbit.oak.plugins.index.IndexConstants.REINDEX_PROPERTY_NAME;
import static org.apache.jackrabbit.oak.plugins.index.IndexUtils.createIndexDefinition;
import static org.apache.jackrabbit.oak.spi.commit.CommitInfo.EMPTY;
import static org.hamcrest.CoreMatchers.containsString;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.junit.Assert.assertEquals;
Expand All @@ -41,6 +45,7 @@
import javax.jcr.RepositoryException;
import javax.jcr.Session;
import javax.jcr.ValueFactory;
import javax.jcr.Workspace;
import javax.jcr.nodetype.NodeTypeManager;
import javax.jcr.query.InvalidQueryException;
import javax.jcr.query.Query;
Expand All @@ -60,6 +65,8 @@
import org.apache.jackrabbit.oak.commons.json.JsopTokenizer;
import org.apache.jackrabbit.oak.fixture.NodeStoreFixture;
import org.apache.jackrabbit.oak.jcr.AbstractRepositoryTest;
import org.apache.jackrabbit.oak.spi.commit.EmptyHook;
import org.apache.jackrabbit.oak.spi.state.NodeBuilder;
import org.junit.Ignore;
import org.junit.Test;

Expand Down Expand Up @@ -138,6 +145,37 @@ public void testSettingsOverride() throws Exception {
assertEquals(90, count);
}

@Test
public void traversalExtendedDiagnosis() throws Exception {
Session session = getAdminSession();
Workspace workspace = session.getWorkspace();
NodeBuilder rootBuilder = getNodeStore().getRoot().builder();
createIndexDefinition(
rootBuilder.child(INDEX_DEFINITIONS_NAME), "foo", true, false,
Set.of("foo"), null);
getNodeStore().merge(rootBuilder, EmptyHook.INSTANCE, EMPTY);
session.refresh(true);
rootBuilder.child("a").setProperty("foo", "abc");
//set reindex=true without a CommitHook to simulate an ongoing re-indexing process.
rootBuilder.child(INDEX_DEFINITIONS_NAME).child("foo").setProperty(REINDEX_PROPERTY_NAME, true);
getNodeStore().merge(rootBuilder, EmptyHook.INSTANCE, EMPTY);
session.refresh(true);
Node foo = session.getNode("/" + INDEX_DEFINITIONS_NAME).getNode("foo");
assertTrue(foo.getProperty(REINDEX_PROPERTY_NAME).getBoolean());
Query query = workspace.getQueryManager().createQuery("select * from [nt:base] where [x] = 1 or [y] = 2 option(traversal fail)", Query.JCR_SQL2);
try {
query.execute();
fail("traversing query should not succeed");
} catch (RepositoryException e) {
String message = e.getMessage();
assertTrue(message.contains("Traversal query (query without index)"));
assertTrue(message.contains("Execution plan"));
assertTrue(message.contains("[nt:base] as [nt:base] /* traverse"));
assertTrue(message.contains("Note that the following indexes were unavailable because of re-indexing"));
assertTrue(message.contains("foo"));
}
}

@Test
public void traversalOption() throws Exception {
Session session = getAdminSession();
Expand Down
Loading