Added: jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/query/SQL2OptimiseQueryTest.java URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/query/SQL2OptimiseQueryTest.java?rev=1709863&view=auto ============================================================================== --- jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/query/SQL2OptimiseQueryTest.java (added) +++ jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/query/SQL2OptimiseQueryTest.java Wed Oct 21 15:19:15 2015 @@ -0,0 +1,248 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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 org.apache.jackrabbit.oak.query; + +import static com.google.common.base.Preconditions.checkNotNull; +import static com.google.common.collect.ImmutableList.of; +import static javax.jcr.query.Query.JCR_SQL2; +import static org.apache.jackrabbit.JcrConstants.JCR_PRIMARYTYPE; +import static org.apache.jackrabbit.JcrConstants.JCR_SYSTEM; +import static org.apache.jackrabbit.oak.api.Type.NAME; +import static org.apache.jackrabbit.oak.plugins.nodetype.NodeTypeConstants.JCR_NODE_TYPES; +import static org.apache.jackrabbit.oak.plugins.nodetype.NodeTypeConstants.NT_OAK_UNSTRUCTURED; +import static org.apache.jackrabbit.oak.query.QueryEngineImpl.ForceOptimised.CHEAPEST; +import static org.apache.jackrabbit.oak.query.QueryEngineImpl.ForceOptimised.OPTIMISED; +import static org.apache.jackrabbit.oak.query.QueryEngineImpl.ForceOptimised.ORIGINAL; +import static org.hamcrest.CoreMatchers.is; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNotSame; +import static org.junit.Assert.assertThat; +import static org.junit.Assert.assertTrue; + +import java.text.ParseException; +import java.util.List; + +import javax.annotation.Nonnull; +import javax.jcr.RepositoryException; + +import org.apache.jackrabbit.oak.Oak; +import org.apache.jackrabbit.oak.api.CommitFailedException; +import org.apache.jackrabbit.oak.api.ContentRepository; +import org.apache.jackrabbit.oak.api.QueryEngine; +import org.apache.jackrabbit.oak.api.Tree; +import org.apache.jackrabbit.oak.namepath.LocalNameMapper; +import org.apache.jackrabbit.oak.namepath.NamePathMapper; +import org.apache.jackrabbit.oak.namepath.NamePathMapperImpl; +import org.apache.jackrabbit.oak.plugins.memory.MemoryNodeStore; +import org.apache.jackrabbit.oak.plugins.nodetype.write.InitialContent; +import org.apache.jackrabbit.oak.spi.security.OpenSecurityProvider; +import org.apache.jackrabbit.oak.spi.state.NodeState; +import org.apache.jackrabbit.oak.spi.state.NodeStore; +import org.junit.Test; + +/** + * aim to cover the various aspects of Query.optimise() + */ +public class SQL2OptimiseQueryTest extends AbstractQueryTest { + private NodeStore store; + private QueryEngineSettings qeSettings = new QueryEngineSettings() { + @Override + public boolean isSql2Optimisation() { + return true; + } + }; + + /** + * checks the {@code Query#optimise()} calls for the conversion from OR to UNION from a query + * POV; ensuring that it returns always the same, expected resultset. + * + * @throws RepositoryException + * @throws CommitFailedException + */ + @Test + public void orToUnions() throws RepositoryException, CommitFailedException { + Tree test, t; + List<String> original, optimised, cheapest, expected; + String statement; + + test = root.getTree("/").addChild("test"); + test.setProperty(JCR_PRIMARYTYPE, NT_OAK_UNSTRUCTURED, NAME); + t = addChildWithProperty(test, "a", "p", "a"); + t.setProperty("p1", "a1"); + t = addChildWithProperty(test, "b", "p", "b"); + t.setProperty("p1", "b1"); + t.setProperty("p2", "a"); + t = addChildWithProperty(test, "c", "p", "c"); + t.setProperty("p3", "a"); + addChildWithProperty(test, "d", "p", "d"); + addChildWithProperty(test, "e", "p", "e"); + test = root.getTree("/").addChild("test2"); + addChildWithProperty(test, "a", "p", "a"); + root.commit(); + + statement = String.format("SELECT * FROM [%s] WHERE p = 'a' OR p = 'b'", + NT_OAK_UNSTRUCTURED); + expected = of("/test/a", "/test/b", "/test2/a"); + setForceOptimised(ORIGINAL); + original = executeQuery(statement, JCR_SQL2, true); + setForceOptimised(OPTIMISED); + optimised = executeQuery(statement, JCR_SQL2, true); + setForceOptimised(CHEAPEST); + cheapest = executeQuery(statement, JCR_SQL2, true); + assertOrToUnionResults(expected, original, optimised, cheapest); + + statement = String.format( + "SELECT * FROM [%s] WHERE p = 'a' OR p = 'b' OR p = 'c' OR p = 'd' OR p = 'e' ", + NT_OAK_UNSTRUCTURED); + expected = of("/test/a", "/test/b", "/test/c", "/test/d", "/test/e", "/test2/a"); + setForceOptimised(ORIGINAL); + original = executeQuery(statement, JCR_SQL2, true); + setForceOptimised(OPTIMISED); + optimised = executeQuery(statement, JCR_SQL2, true); + setForceOptimised(CHEAPEST); + cheapest = executeQuery(statement, JCR_SQL2, true); + assertOrToUnionResults(expected, original, optimised, cheapest); + + statement = String.format( + "SELECT * FROM [%s] WHERE (p = 'a' OR p = 'b') AND (p1 = 'a1' OR p1 = 'b1')", + NT_OAK_UNSTRUCTURED); + expected = of("/test/a", "/test/b"); + setForceOptimised(ORIGINAL); + original = executeQuery(statement, JCR_SQL2, true); + setForceOptimised(OPTIMISED); + optimised = executeQuery(statement, JCR_SQL2, true); + setForceOptimised(CHEAPEST); + cheapest = executeQuery(statement, JCR_SQL2, true); + assertOrToUnionResults(expected, original, optimised, cheapest); + + statement = String.format( + "SELECT * FROM [%s] WHERE (p = 'a' AND p1 = 'a1') OR (p = 'b' AND p1 = 'b1')", + NT_OAK_UNSTRUCTURED); + expected = of("/test/a", "/test/b"); + setForceOptimised(ORIGINAL); + original = executeQuery(statement, JCR_SQL2, true); + setForceOptimised(OPTIMISED); + optimised = executeQuery(statement, JCR_SQL2, true); + setForceOptimised(CHEAPEST); + cheapest = executeQuery(statement, JCR_SQL2, true); + assertOrToUnionResults(expected, original, optimised, cheapest); + + statement = "SELECT * FROM [oak:Unstructured] AS c " + + "WHERE ( c.[p] = 'a' " + + "OR c.[p2] = 'a' " + + "OR c.[p3] = 'a') " + + "AND ISDESCENDANTNODE(c, '/test') " + + "ORDER BY added DESC"; + expected = of("/test/a", "/test/b", "/test/c"); + setForceOptimised(ORIGINAL); + original = executeQuery(statement, JCR_SQL2, true); + setForceOptimised(OPTIMISED); + optimised = executeQuery(statement, JCR_SQL2, true); + setForceOptimised(CHEAPEST); + cheapest = executeQuery(statement, JCR_SQL2, true); + assertOrToUnionResults(expected, original, optimised, cheapest); + } + + private static void assertOrToUnionResults(@Nonnull List<String> expected, + @Nonnull List<String> original, + @Nonnull List<String> optimised, + @Nonnull List<String> cheapest) { + // checks that all the three list are the expected content + assertThat(checkNotNull(original), is(checkNotNull(expected))); + assertThat(checkNotNull(optimised), is(expected)); + assertThat(checkNotNull(cheapest), is(expected)); + + // check that all the three lists contains the same. Paranoid but still a fast check + assertThat(original, is(optimised)); + assertThat(optimised, is(cheapest)); + assertThat(cheapest, is(original)); + } + + private static Tree addChildWithProperty(@Nonnull Tree father, @Nonnull String name, + @Nonnull String propName, @Nonnull String propValue) { + Tree t = checkNotNull(father).addChild(checkNotNull(name)); + t.setProperty(JCR_PRIMARYTYPE, NT_OAK_UNSTRUCTURED, NAME); + t.setProperty(checkNotNull(propName), checkNotNull(propValue)); + return t; + } + + /** + * ensure that an optimisation is available for the provided queries. + * + * @throws ParseException + */ + @Test + public void optimise() throws ParseException { + SQL2Parser parser = new SQL2Parser(getMappings(), getTypes(), qeSettings); + String statement; + Query original, optimised; + + statement = + "SELECT * FROM [nt:unstructured] AS c " + + "WHERE " + + "(c.[p1]='a' OR c.[p2]='b') "; + original = parser.parse(statement, false); + assertNotNull(original); + optimised = original.optimise(); + assertNotNull(optimised); + assertNotSame(original, optimised); + assertTrue(optimised instanceof UnionQueryImpl); + + statement = + "SELECT * FROM [nt:unstructured] AS c " + + "WHERE " + + "(c.[p1]='a' OR c.[p2]='b') " + + "AND " + + "ISDESCENDANTNODE(c, '/test') "; + original = parser.parse(statement, false); + assertNotNull(original); + optimised = original.optimise(); + assertNotNull(optimised); + assertNotSame(original, optimised); + + statement = + "SELECT * FROM [nt:unstructured] AS c " + + "WHERE " + + "(c.[p1]='a' OR c.[p2]='b' OR c.[p3]='c') " + + "AND " + + "ISDESCENDANTNODE(c, '/test') "; + original = parser.parse(statement, false); + assertNotNull(original); + optimised = original.optimise(); + assertNotNull(optimised); + assertNotSame(original, optimised); + } + + private NamePathMapper getMappings() { + return new NamePathMapperImpl( + new LocalNameMapper(root, QueryEngine.NO_MAPPINGS)); + } + + private NodeState getTypes() { + return store.getRoot().getChildNode(JCR_SYSTEM).getChildNode(JCR_NODE_TYPES); + } + + @Override + protected ContentRepository createRepository() { + store = new MemoryNodeStore(); + return new Oak(store) + .with(new OpenSecurityProvider()) + .with(new InitialContent()) + .with(qeSettings) + .createContentRepository(); + } +}
Added: jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/query/ast/AndImplTest.java URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/query/ast/AndImplTest.java?rev=1709863&view=auto ============================================================================== --- jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/query/ast/AndImplTest.java (added) +++ jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/query/ast/AndImplTest.java Wed Oct 21 15:19:15 2015 @@ -0,0 +1,81 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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 org.apache.jackrabbit.oak.query.ast; + +import static com.google.common.base.Preconditions.checkNotNull; +import static com.google.common.collect.ImmutableSet.of; +import static java.util.Collections.emptySet; +import static org.hamcrest.CoreMatchers.is; +import static org.junit.Assert.assertThat; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +import java.util.Set; + +import javax.annotation.Nonnull; + +import org.junit.Test; + +public class AndImplTest { + @Test + public void simplifyForUnion() { + ConstraintImpl and, op1, op2, op3, op4; + Set<ConstraintImpl> expected; + + op1 = mock(ComparisonImpl.class); + op2 = mock(ComparisonImpl.class); + and = new AndImpl(op1, op2); + expected = emptySet(); + assertThat(and.simplifyForUnion(), is(expected)); + + op1 = mockConstraint("op1", ComparisonImpl.class); + op2 = mockConstraint("op2", ComparisonImpl.class); + op3 = mockConstraint("op3", ComparisonImpl.class); + and = new AndImpl(new OrImpl(op1, op2), op3); + expected = of( + (ConstraintImpl) new AndImpl(op1, op3) + , (ConstraintImpl) new AndImpl(op2, op3) + ); + assertThat(and.simplifyForUnion(), is(expected)); + + op1 = mockConstraint("op1", ComparisonImpl.class); + op2 = mockConstraint("op2", ComparisonImpl.class); + op3 = mockConstraint("op3", ComparisonImpl.class); + op4 = mockConstraint("op4", ComparisonImpl.class); + and = new AndImpl(new OrImpl(new OrImpl(op1, op4), op2), op3); + expected = of( + (ConstraintImpl) new AndImpl(op1, op3) + , (ConstraintImpl) new AndImpl(op2, op3) + , (ConstraintImpl) new AndImpl(op4, op3) + ); + assertThat(and.simplifyForUnion(), is(expected)); +} + + /** + * convenience method for having better assertion messages + * + * @param toString the {@link String#toString()} message to be shown. Cannot be null; + * @param clazz the class you want Mockito to generate for you. + * @return a Mockito instance of the provided ConstraintImpl + */ + private static ConstraintImpl mockConstraint(@Nonnull String toString, + @Nonnull Class<? extends ConstraintImpl> clazz) { + ConstraintImpl c = mock(checkNotNull(clazz)); + when(c.toString()).thenReturn(checkNotNull(toString)); + return c; + } +} Added: jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/query/ast/OrImplTest.java URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/query/ast/OrImplTest.java?rev=1709863&view=auto ============================================================================== --- jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/query/ast/OrImplTest.java (added) +++ jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/query/ast/OrImplTest.java Wed Oct 21 15:19:15 2015 @@ -0,0 +1,55 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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 org.apache.jackrabbit.oak.query.ast; + +import static com.google.common.collect.ImmutableSet.of; +import static org.hamcrest.CoreMatchers.is; +import static org.junit.Assert.assertThat; +import static org.mockito.Mockito.mock; + +import java.util.Set; + +import org.junit.Test; + +public class OrImplTest { + @Test + public void simplifyForUnion() { + ConstraintImpl op1, op2, op3, op4, or; + Set<ConstraintImpl> expected; + + op1 = mock(ComparisonImpl.class); + op2 = mock(ComparisonImpl.class); + or = new OrImpl(op1, op2); + expected = of(op1, op2); + assertThat(or.simplifyForUnion(), is(expected)); + + op1 = mock(ComparisonImpl.class); + op2 = mock(ComparisonImpl.class); + op3 = mock(ComparisonImpl.class); + or = new OrImpl(new OrImpl(op1, op2), op3); + expected = of(op1, op2, op3); + assertThat(or.simplifyForUnion(), is(expected)); + + op1 = mock(ComparisonImpl.class); + op2 = mock(ComparisonImpl.class); + op3 = mock(ComparisonImpl.class); + op4 = mock(ComparisonImpl.class); + or = new OrImpl(new OrImpl(new OrImpl(op1, op4), op2), op3); + expected = of(op1, op2, op3, op4); + assertThat(or.simplifyForUnion(), is(expected)); + } +} Modified: jackrabbit/oak/trunk/oak-lucene/src/test/java/org/apache/jackrabbit/oak/plugins/index/lucene/LuceneIndexQueryTest.java URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-lucene/src/test/java/org/apache/jackrabbit/oak/plugins/index/lucene/LuceneIndexQueryTest.java?rev=1709863&r1=1709862&r2=1709863&view=diff ============================================================================== --- jackrabbit/oak/trunk/oak-lucene/src/test/java/org/apache/jackrabbit/oak/plugins/index/lucene/LuceneIndexQueryTest.java (original) +++ jackrabbit/oak/trunk/oak-lucene/src/test/java/org/apache/jackrabbit/oak/plugins/index/lucene/LuceneIndexQueryTest.java Wed Oct 21 15:19:15 2015 @@ -17,12 +17,9 @@ package org.apache.jackrabbit.oak.plugins.index.lucene; import com.google.common.collect.ImmutableList; -import com.google.common.collect.Lists; import java.util.ArrayList; -import java.util.Calendar; import java.util.Iterator; -import java.util.List; import org.apache.jackrabbit.oak.Oak; import org.apache.jackrabbit.oak.api.ContentRepository; @@ -42,7 +39,6 @@ import static java.util.Arrays.asList; import static junit.framework.Assert.assertEquals; import static org.apache.jackrabbit.JcrConstants.JCR_PRIMARYTYPE; import static org.apache.jackrabbit.JcrConstants.NT_UNSTRUCTURED; -import static org.apache.jackrabbit.oak.api.Type.NAME; import static org.apache.jackrabbit.oak.api.Type.STRING; import static org.apache.jackrabbit.oak.api.Type.STRINGS; import static org.apache.jackrabbit.oak.plugins.index.lucene.TestUtil.useV2; @@ -67,21 +63,26 @@ public class LuceneIndexQueryTest extend props.getParent().setProperty(LuceneIndexConstants.INDEX_NODE_NAME, true); TestUtil.enablePropertyIndex(props, "c1/p", false); TestUtil.enableForFullText(props, LuceneIndexConstants.REGEX_ALL_PROPS, true); - - root.commit(); + TestUtil.enablePropertyIndex(props, "a/name", false); + TestUtil.enablePropertyIndex(props, "b/name", false); + + root.commit(); } - + @Override protected ContentRepository createRepository() { + return getOakRepo().createContentRepository(); + } + + Oak getOakRepo() { LowCostLuceneIndexProvider provider = new LowCostLuceneIndexProvider(); return new Oak().with(new InitialContent()) - .with(new OpenSecurityProvider()) - .with((QueryIndexProvider) provider) - .with((Observer) provider) - .with(new LuceneIndexEditorProvider()) - .createContentRepository(); + .with(new OpenSecurityProvider()) + .with((QueryIndexProvider) provider) + .with((Observer) provider) + .with(new LuceneIndexEditorProvider()); } - + @Test public void sql1() throws Exception { test("sql1.txt"); @@ -375,109 +376,6 @@ public class LuceneIndexQueryTest extend } @Test - @Ignore - public void oak2660() throws Exception { - final String name = "name"; - final String surname = "surname"; - final String description = "description"; - final String added = "added"; - final String yes = "yes"; - - Tree t; - - // re-define the lucene index - t = root.getTree("/oak:index/" + TEST_INDEX_NAME); - assertTrue(t.exists()); - t.remove(); - root.commit(); - assertFalse(root.getTree("/oak:index/" + TEST_INDEX_NAME).exists()); - - t = root.getTree("/"); - Tree indexDefn = createTestIndexNode(t, LuceneIndexConstants.TYPE_LUCENE); - useV2(indexDefn); - indexDefn.setProperty(LuceneIndexConstants.TEST_MODE, true); - - Tree props = TestUtil.newRulePropTree(indexDefn, NT_UNSTRUCTURED); - TestUtil.enablePropertyIndex(props, name, false); - TestUtil.enableForFullText(props, surname, false); - TestUtil.enableForFullText(props, description, false); - TestUtil.enableForOrdered(props, added); - - root.commit(); - - // creating the dataset - List<String> expected = Lists.newArrayList(); - Tree content = root.getTree("/").addChild("content"); - t = content.addChild("test1"); - t.setProperty(JCR_PRIMARYTYPE, NT_UNSTRUCTURED, NAME); - t.setProperty(name, yes); - t.setProperty(surname, yes); - t.setProperty(description, yes); - t.setProperty(added, Calendar.getInstance()); - expected.add(t.getPath()); - - t = content.addChild("test2"); - t.setProperty(JCR_PRIMARYTYPE, NT_UNSTRUCTURED, NAME); - t.setProperty(name, yes); - t.setProperty(surname, yes); - t.setProperty(description, "no"); - t.setProperty(added, Calendar.getInstance()); - expected.add(t.getPath()); - - t = content.addChild("test3"); - t.setProperty(JCR_PRIMARYTYPE, NT_UNSTRUCTURED, NAME); - t.setProperty(name, yes); - t.setProperty(surname, "no"); - t.setProperty(description, "no"); - t.setProperty(added, Calendar.getInstance()); - expected.add(t.getPath()); - - t = content.addChild("test4"); - t.setProperty(JCR_PRIMARYTYPE, NT_UNSTRUCTURED, NAME); - t.setProperty(name, "no"); - t.setProperty(surname, yes); - t.setProperty(description, "no"); - t.setProperty(added, Calendar.getInstance()); - expected.add(t.getPath()); - - t = content.addChild("test5"); - t.setProperty(JCR_PRIMARYTYPE, NT_UNSTRUCTURED, NAME); - t.setProperty(name, "no"); - t.setProperty(surname, "no"); - t.setProperty(description, yes); - t.setProperty(added, Calendar.getInstance()); - expected.add(t.getPath()); - - t = content.addChild("test6"); - t.setProperty(JCR_PRIMARYTYPE, NT_UNSTRUCTURED, NAME); - t.setProperty(name, "no"); - t.setProperty(surname, "no"); - t.setProperty(description, "no"); - t.setProperty(added, Calendar.getInstance()); - - root.commit(); - - // asserting the initial state - for (String s : expected) { - assertTrue("wrong initial state", root.getTree(s).exists()); - } - - final String statement = - "SELECT * " + - "FROM [" + NT_UNSTRUCTURED + "] AS c " + - "WHERE " + - "( " + - "c.[" + name + "] = '" + yes + "' " + - "OR CONTAINS(c.[" + surname + "], '" + yes + "') " + - "OR CONTAINS(c.[" + description + "], '" + yes + "') " + - ") " + - "AND ISDESCENDANTNODE(c, '" + content.getPath() + "') " + - "ORDER BY " + added + " DESC "; - - assertQuery(statement, SQL2, expected); - } - - @Test public void testMultiValuedPropUpdate() throws Exception { Tree test = root.getTree("/").addChild("test"); String child = "child"; Added: jackrabbit/oak/trunk/oak-lucene/src/test/java/org/apache/jackrabbit/oak/plugins/index/lucene/LuceneIndexQueryTestSQL2Optimisation.java URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-lucene/src/test/java/org/apache/jackrabbit/oak/plugins/index/lucene/LuceneIndexQueryTestSQL2Optimisation.java?rev=1709863&view=auto ============================================================================== --- jackrabbit/oak/trunk/oak-lucene/src/test/java/org/apache/jackrabbit/oak/plugins/index/lucene/LuceneIndexQueryTestSQL2Optimisation.java (added) +++ jackrabbit/oak/trunk/oak-lucene/src/test/java/org/apache/jackrabbit/oak/plugins/index/lucene/LuceneIndexQueryTestSQL2Optimisation.java Wed Oct 21 15:19:15 2015 @@ -0,0 +1,149 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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 org.apache.jackrabbit.oak.plugins.index.lucene; + +import static org.apache.jackrabbit.JcrConstants.JCR_PRIMARYTYPE; +import static org.apache.jackrabbit.JcrConstants.NT_UNSTRUCTURED; +import static org.apache.jackrabbit.oak.api.Type.NAME; +import static org.apache.jackrabbit.oak.plugins.index.lucene.TestUtil.useV2; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; + +import java.util.Calendar; +import java.util.List; + +import org.apache.jackrabbit.oak.Oak; +import org.apache.jackrabbit.oak.api.Tree; +import org.apache.jackrabbit.oak.query.QueryEngineSettings; +import org.junit.Test; + +import com.google.common.collect.Lists; + +public class LuceneIndexQueryTestSQL2Optimisation extends LuceneIndexQueryTest { + + @Override + Oak getOakRepo() { + return super.getOakRepo().with(new QueryEngineSettings() { + @Override + public boolean isSql2Optimisation() { + return true; + } + }); + } + + @Test + public void oak2660() throws Exception { + final String name = "name"; + final String surname = "surname"; + final String description = "description"; + final String added = "added"; + final String yes = "yes"; + + Tree t; + + // re-define the lucene index + t = root.getTree("/oak:index/" + TEST_INDEX_NAME); + assertTrue(t.exists()); + t.remove(); + root.commit(); + assertFalse(root.getTree("/oak:index/" + TEST_INDEX_NAME).exists()); + + t = root.getTree("/"); + Tree indexDefn = createTestIndexNode(t, LuceneIndexConstants.TYPE_LUCENE); + useV2(indexDefn); + indexDefn.setProperty(LuceneIndexConstants.TEST_MODE, true); + + Tree props = TestUtil.newRulePropTree(indexDefn, NT_UNSTRUCTURED); + TestUtil.enablePropertyIndex(props, name, false); + TestUtil.enableForFullText(props, surname, false); + TestUtil.enableForFullText(props, description, false); + TestUtil.enableForOrdered(props, added); + + root.commit(); + + // creating the dataset + List<String> expected = Lists.newArrayList(); + Tree content = root.getTree("/").addChild("content"); + t = content.addChild("test1"); + t.setProperty(JCR_PRIMARYTYPE, NT_UNSTRUCTURED, NAME); + t.setProperty(name, yes); + t.setProperty(surname, yes); + t.setProperty(description, yes); + t.setProperty(added, Calendar.getInstance()); + expected.add(t.getPath()); + + t = content.addChild("test2"); + t.setProperty(JCR_PRIMARYTYPE, NT_UNSTRUCTURED, NAME); + t.setProperty(name, yes); + t.setProperty(surname, yes); + t.setProperty(description, "no"); + t.setProperty(added, Calendar.getInstance()); + expected.add(t.getPath()); + + t = content.addChild("test3"); + t.setProperty(JCR_PRIMARYTYPE, NT_UNSTRUCTURED, NAME); + t.setProperty(name, yes); + t.setProperty(surname, "no"); + t.setProperty(description, "no"); + t.setProperty(added, Calendar.getInstance()); + expected.add(t.getPath()); + + t = content.addChild("test4"); + t.setProperty(JCR_PRIMARYTYPE, NT_UNSTRUCTURED, NAME); + t.setProperty(name, "no"); + t.setProperty(surname, yes); + t.setProperty(description, "no"); + t.setProperty(added, Calendar.getInstance()); + expected.add(t.getPath()); + + t = content.addChild("test5"); + t.setProperty(JCR_PRIMARYTYPE, NT_UNSTRUCTURED, NAME); + t.setProperty(name, "no"); + t.setProperty(surname, "no"); + t.setProperty(description, yes); + t.setProperty(added, Calendar.getInstance()); + expected.add(t.getPath()); + + t = content.addChild("test6"); + t.setProperty(JCR_PRIMARYTYPE, NT_UNSTRUCTURED, NAME); + t.setProperty(name, "no"); + t.setProperty(surname, "no"); + t.setProperty(description, "no"); + t.setProperty(added, Calendar.getInstance()); + + root.commit(); + + // asserting the initial state + for (String s : expected) { + assertTrue("wrong initial state", root.getTree(s).exists()); + } + + final String statement = + "SELECT * " + + "FROM [" + NT_UNSTRUCTURED + "] AS c " + + "WHERE " + + "( " + + "c.[" + name + "] = '" + yes + "' " + + "OR CONTAINS(c.[" + surname + "], '" + yes + "') " + + "OR CONTAINS(c.[" + description + "], '" + yes + "') " + + ") " + + "AND ISDESCENDANTNODE(c, '" + content.getPath() + "') " + + "ORDER BY " + added + " DESC "; + + assertQuery(statement, SQL2, expected); + } +} Modified: jackrabbit/oak/trunk/oak-solr-core/pom.xml URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-solr-core/pom.xml?rev=1709863&r1=1709862&r2=1709863&view=diff ============================================================================== --- jackrabbit/oak/trunk/oak-solr-core/pom.xml (original) +++ jackrabbit/oak/trunk/oak-solr-core/pom.xml Wed Oct 21 15:19:15 2015 @@ -60,6 +60,10 @@ org.apache.jackrabbit.core.query.ExcerptTest#testPunctuationStartsFragmentEndsWithDots <!-- OAK-318 --> org.apache.jackrabbit.core.query.ExcerptTest#testPreferPhrase <!-- OAK-318 --> org.apache.jackrabbit.oak.jcr.query.SpellcheckTest#testSpellcheckMultipleWords <!-- FIXME OAK-3355 --> + + org.apache.jackrabbit.core.query.JoinTest#testJoinWithOR3 <!-- OAK-3437 --> + org.apache.jackrabbit.core.query.JoinTest#testJoinWithOR4 <!-- OAK-3437 --> + org.apache.jackrabbit.core.query.JoinTest#testJoinWithOR5 <!-- OAK-3437 --> </known.issues> </properties>
