Skip to content

Instantly share code, notes, and snippets.

@bdelacretaz
Created May 29, 2015 15:30
Show Gist options
  • Save bdelacretaz/fe6808ee7e04d23fb77c to your computer and use it in GitHub Desktop.
Save bdelacretaz/fe6808ee7e04d23fb77c to your computer and use it in GitHub Desktop.
Oak query conversion, experimental patch
Index: oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/DescendantNodeImpl.java
===================================================================
--- oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/DescendantNodeImpl.java (revision 1682417)
+++ oak-core/src/main/java/org/apache/jackrabbit/oak/query/ast/DescendantNodeImpl.java (working copy)
@@ -48,6 +48,10 @@
public Set<SelectorImpl> getSelectors() {
return Collections.singleton(selector);
}
+
+ public String getAncestorPath() {
+ return ancestorPath;
+ }
@Override
public boolean evaluate() {
Index: oak-core/src/test/java/org/apache/jackrabbit/oak/query/QueryConverterTest.java
===================================================================
--- oak-core/src/test/java/org/apache/jackrabbit/oak/query/QueryConverterTest.java (revision 0)
+++ oak-core/src/test/java/org/apache/jackrabbit/oak/query/QueryConverterTest.java (working copy)
@@ -0,0 +1,195 @@
+/*
+ * 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 org.junit.Assert.assertEquals;
+
+import java.text.ParseException;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.concurrent.atomic.AtomicInteger;
+
+import org.apache.jackrabbit.oak.namepath.NamePathMapper;
+import org.apache.jackrabbit.oak.query.ast.AstVisitorBase;
+import org.apache.jackrabbit.oak.query.ast.BindVariableValueImpl;
+import org.apache.jackrabbit.oak.query.ast.ChildNodeImpl;
+import org.apache.jackrabbit.oak.query.ast.ChildNodeJoinConditionImpl;
+import org.apache.jackrabbit.oak.query.ast.ColumnImpl;
+import org.apache.jackrabbit.oak.query.ast.DescendantNodeImpl;
+import org.apache.jackrabbit.oak.query.ast.DescendantNodeJoinConditionImpl;
+import org.apache.jackrabbit.oak.query.ast.EquiJoinConditionImpl;
+import org.apache.jackrabbit.oak.query.ast.FullTextSearchScoreImpl;
+import org.apache.jackrabbit.oak.query.ast.LiteralImpl;
+import org.apache.jackrabbit.oak.query.ast.NodeLocalNameImpl;
+import org.apache.jackrabbit.oak.query.ast.NodeNameImpl;
+import org.apache.jackrabbit.oak.query.ast.PropertyExistenceImpl;
+import org.apache.jackrabbit.oak.query.ast.PropertyInexistenceImpl;
+import org.apache.jackrabbit.oak.query.ast.PropertyValueImpl;
+import org.apache.jackrabbit.oak.query.ast.SameNodeImpl;
+import org.apache.jackrabbit.oak.query.ast.SameNodeJoinConditionImpl;
+import org.apache.jackrabbit.oak.query.ast.SelectorImpl;
+import org.apache.jackrabbit.oak.query.xpath.XPathToSQL2Converter;
+import org.apache.jackrabbit.oak.spi.state.NodeState;
+import org.junit.Test;
+import org.mockito.Matchers;
+import org.mockito.Mockito;
+
+public class QueryConverterTest {
+ @Test
+ public void testConvertFromSQL() throws Exception {
+ final AtomicInteger counter = new AtomicInteger();
+ final NamePathMapper nmp = Mockito.mock(NamePathMapper.class);
+ Mockito.when(nmp.getOakName(Matchers.anyString())).thenReturn("nt:test");
+ Mockito.when(nmp.getJcrName(Matchers.anyString())).thenReturn("foo" + counter.incrementAndGet());
+
+ final NodeState types = Mockito.mock(NodeState.class);
+ final NodeState typeExists = Mockito.mock(NodeState.class);
+ Mockito.when(typeExists.exists()).thenReturn(true);
+
+ final List<String> supertypes = new ArrayList<String>();
+ supertypes.add("nt:super");
+
+ Mockito.when(typeExists.getNames(Matchers.anyString())).thenReturn(supertypes);
+ Mockito.when(types.getChildNode(Matchers.anyString())).thenReturn(typeExists);
+
+ final QueryEngineSettings settings = new QueryEngineSettings();
+ final SQL2Parser parser = new SQL2Parser(nmp, types, settings);
+ final Query q = parser.parse("select * from [nt:unstructured] where isDescendantNode('/content') and name='x42' /* sql comment */");
+
+ final StringBuilder b = new StringBuilder();
+
+ final AstVisitorBase v = new AstVisitorBase() {
+
+ @Override
+ public boolean visit(SelectorImpl node) {
+ b.append(" TYPE ").append(node.getSelectorName());
+ return false;
+ }
+
+ @Override
+ public boolean visit(SameNodeJoinConditionImpl node) {
+ // TODO Auto-generated method stub
+ return false;
+ }
+
+ @Override
+ public boolean visit(SameNodeImpl node) {
+ // TODO Auto-generated method stub
+ return false;
+ }
+
+ @Override
+ public boolean visit(PropertyValueImpl node) {
+ b.append(" PROPVAL ").append(node);
+ return false;
+ }
+
+ @Override
+ public boolean visit(PropertyInexistenceImpl node) {
+ // TODO Auto-generated method stub
+ return false;
+ }
+
+ @Override
+ public boolean visit(PropertyExistenceImpl node) {
+ // TODO Auto-generated method stub
+ return false;
+ }
+
+ @Override
+ public boolean visit(NodeNameImpl node) {
+ // TODO Auto-generated method stub
+ return false;
+ }
+
+ @Override
+ public boolean visit(NodeLocalNameImpl node) {
+ // TODO Auto-generated method stub
+ return false;
+ }
+
+ @Override
+ public boolean visit(LiteralImpl node) {
+ // TODO Auto-generated method stub
+ return false;
+ }
+
+ @Override
+ public boolean visit(FullTextSearchScoreImpl node) {
+ // TODO Auto-generated method stub
+ return false;
+ }
+
+ @Override
+ public boolean visit(EquiJoinConditionImpl node) {
+ // TODO Auto-generated method stub
+ return false;
+ }
+
+ @Override
+ public boolean visit(DescendantNodeJoinConditionImpl node) {
+ // TODO Auto-generated method stub
+ return false;
+ }
+
+ @Override
+ public boolean visit(DescendantNodeImpl node) {
+ b.append(" DESC ").append(node.getAncestorPath());
+ return false;
+ }
+
+ @Override
+ public boolean visit(ColumnImpl node) {
+ // TODO Auto-generated method stub
+ return false;
+ }
+
+ @Override
+ public boolean visit(ChildNodeJoinConditionImpl node) {
+ // TODO Auto-generated method stub
+ return false;
+ }
+
+ @Override
+ public boolean visit(ChildNodeImpl node) {
+ // TODO Auto-generated method stub
+ return false;
+ }
+
+ @Override
+ public boolean visit(BindVariableValueImpl node) {
+ // TODO Auto-generated method stub
+ return false;
+ }
+ };
+
+ final QueryImpl needToCastForNow = (QueryImpl)q;
+ v.visit(needToCastForNow);
+ final String expected = "TYPE nt:test DESC /content PROPVAL [nt:test].[name]";
+ assertEquals(expected, b.toString().trim());
+ }
+
+ @Test
+ public void testXPathConverter() throws ParseException {
+ final XPathToSQL2Converter c = new XPathToSQL2Converter();
+ final String stmt = "/jcr:root/test/*/nt:resource[@jcr:encoding]";
+
+ final String expected = "select b.[jcr:path] as [jcr:path], b.[jcr:score] as [jcr:score], b.* from [nt:base] as a inner join [nt:base] as b on ischildnode(b, a) where ischildnode(a, '/test') and b.[jcr:encoding] is not null and name(b) = 'nt:resource' /* xpath: /jcr:root/test/* /nt:resource[@jcr:encoding] */";
+ final String actual = c.convert(stmt);
+ assertEquals(expected, actual);
+ }
+}
\ No newline at end of file
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment