You are viewing a plain text version of this content. The canonical link for it is here.
Posted to oak-commits@jackrabbit.apache.org by th...@apache.org on 2018/09/19 13:53:44 UTC

svn commit: r1841340 - in /jackrabbit/oak/trunk: oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/ oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/aggregate/ oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/pr...

Author: thomasm
Date: Wed Sep 19 13:53:44 2018
New Revision: 1841340

URL: http://svn.apache.org/viewvc?rev=1841340&view=rev
Log:
OAK-7768: Ability to deprecate an index

Added:
    jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/index/property/PropertyIndexDeprecatedTest.java
Modified:
    jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/IndexConstants.java
    jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/aggregate/AggregateIndexPlan.java
    jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/property/PropertyIndexPlan.java
    jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/index/property/PropertyIndexDisabledTest.java
    jackrabbit/oak/trunk/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/IndexDefinition.java
    jackrabbit/oak/trunk/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/LuceneIndex.java
    jackrabbit/oak/trunk/oak-query-spi/src/main/java/org/apache/jackrabbit/oak/spi/query/QueryIndex.java
    jackrabbit/oak/trunk/oak-query-spi/src/main/java/org/apache/jackrabbit/oak/spi/query/package-info.java

Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/IndexConstants.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/IndexConstants.java?rev=1841340&r1=1841339&r2=1841340&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/IndexConstants.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/IndexConstants.java Wed Sep 19 13:53:44 2018
@@ -141,10 +141,15 @@ public interface IndexConstants {
     String DISABLE_INDEXES_ON_NEXT_CYCLE = ":disableIndexesOnNextCycle";
     
     /**
-     * The property of an index. If the given node or property exists, then the
+     * Whether to use the index. If the given node or property exists, then the
      * index is used for queries; otherwise, it is not used (returns infinite
      * cost). The value is: nodes, the path. For properties, the path of the node, then '@' property.
      */
     String USE_IF_EXISTS = "useIfExists";
+    
+    /**
+     * Whether the index is deprecated. If it is, and the index is used, a warning is logged.
+     */
+    String INDEX_DEPRECATED = "deprecated";
 
 }

Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/aggregate/AggregateIndexPlan.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/aggregate/AggregateIndexPlan.java?rev=1841340&r1=1841339&r2=1841340&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/aggregate/AggregateIndexPlan.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/aggregate/AggregateIndexPlan.java Wed Sep 19 13:53:44 2018
@@ -129,6 +129,16 @@ public class AggregateIndexPlan implemen
         }
         return false;
     }
+    
+    @Override
+    public boolean isDeprecated() {
+        for (IndexPlan p : basePlans.values()) {
+            if (p != null && p.isDeprecated()) {
+                return true;
+            }
+        }
+        return false;
+    }
 
     /**
      * Whether any base plan is a full text index.

Modified: jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/property/PropertyIndexPlan.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/property/PropertyIndexPlan.java?rev=1841340&r1=1841339&r2=1841340&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/property/PropertyIndexPlan.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/index/property/PropertyIndexPlan.java Wed Sep 19 13:53:44 2018
@@ -27,9 +27,11 @@ import static org.apache.jackrabbit.oak.
 import java.util.List;
 import java.util.Set;
 
+import org.apache.jackrabbit.oak.api.PropertyState;
 import org.apache.jackrabbit.oak.commons.PathUtils;
 import org.apache.jackrabbit.oak.plugins.index.Cursors;
 import org.apache.jackrabbit.oak.plugins.index.IndexConstants;
+import org.apache.jackrabbit.oak.plugins.index.property.strategy.ContentMirrorStoreStrategy;
 import org.apache.jackrabbit.oak.plugins.index.property.strategy.IndexStoreStrategy;
 import org.apache.jackrabbit.oak.spi.filter.PathFilter;
 import org.apache.jackrabbit.oak.spi.mount.MountInfoProvider;
@@ -39,6 +41,8 @@ import org.apache.jackrabbit.oak.spi.que
 import org.apache.jackrabbit.oak.spi.query.Filter.PropertyRestriction;
 import org.apache.jackrabbit.oak.spi.query.QueryLimits;
 import org.apache.jackrabbit.oak.spi.state.NodeState;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
 import com.google.common.collect.Iterables;
 import com.google.common.collect.Lists;
@@ -47,6 +51,8 @@ import com.google.common.collect.Lists;
  * Plan for querying a given property index using a given filter.
  */
 public class PropertyIndexPlan {
+    
+    static final Logger LOG = LoggerFactory.getLogger(PropertyIndexPlan.class);
 
     /**
      * The cost overhead to use the index in number of read operations.
@@ -82,6 +88,8 @@ public class PropertyIndexPlan {
 
     private final boolean unique;
     
+    private final boolean deprecated;
+    
     PropertyIndexPlan(String name, NodeState root, NodeState definition,
                       Filter filter){
         this(name, root, definition, filter, Mounts.defaultMountInfoProvider());
@@ -100,6 +108,7 @@ public class PropertyIndexPlan {
         Iterable<String> types = definition.getNames(DECLARING_NODE_TYPES);
         // if there is no such property, then all nodetypes are matched
         this.matchesAllTypes = !definition.hasProperty(DECLARING_NODE_TYPES);
+        this.deprecated = definition.getBoolean(IndexConstants.INDEX_DEPRECATED);
         this.matchesNodeTypes =
                 matchesAllTypes || any(types, in(filter.getSupertypes()));
 
@@ -198,6 +207,10 @@ public class PropertyIndexPlan {
     }
 
     Cursor execute() {
+        if (deprecated) {
+            LOG.warn("This index is deprecated: {}; it is used for query {}. " + 
+                    "Please change the query or the index definitions.", name, filter);
+        }
         QueryLimits settings = filter.getQueryLimits();
         List<Iterable<String>> iterables = Lists.newArrayList();
         for (IndexStoreStrategy s : strategies) {

Added: jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/index/property/PropertyIndexDeprecatedTest.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/index/property/PropertyIndexDeprecatedTest.java?rev=1841340&view=auto
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/index/property/PropertyIndexDeprecatedTest.java (added)
+++ jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/index/property/PropertyIndexDeprecatedTest.java Wed Sep 19 13:53:44 2018
@@ -0,0 +1,188 @@
+/*
+ * 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.property;
+
+import static org.apache.jackrabbit.JcrConstants.NT_BASE;
+import static org.apache.jackrabbit.oak.plugins.index.IndexConstants.INDEX_DEFINITIONS_NAME;
+import static org.apache.jackrabbit.oak.plugins.index.IndexUtils.createIndexDefinition;
+import static org.apache.jackrabbit.oak.spi.commit.CommitInfo.EMPTY;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+import java.util.List;
+
+import org.apache.jackrabbit.oak.InitialContentHelper;
+import org.apache.jackrabbit.oak.plugins.index.IndexConstants;
+import org.apache.jackrabbit.oak.plugins.index.IndexUpdateProvider;
+import org.apache.jackrabbit.oak.plugins.memory.EmptyNodeState;
+import org.apache.jackrabbit.oak.plugins.memory.PropertyValues;
+import org.apache.jackrabbit.oak.query.NodeStateNodeTypeInfoProvider;
+import org.apache.jackrabbit.oak.query.QueryEngineSettings;
+import org.apache.jackrabbit.oak.query.ast.NodeTypeInfo;
+import org.apache.jackrabbit.oak.query.ast.NodeTypeInfoProvider;
+import org.apache.jackrabbit.oak.query.ast.Operator;
+import org.apache.jackrabbit.oak.query.ast.SelectorImpl;
+import org.apache.jackrabbit.oak.query.index.FilterImpl;
+import org.apache.jackrabbit.oak.spi.commit.EditorHook;
+import org.apache.jackrabbit.oak.spi.mount.Mounts;
+import org.apache.jackrabbit.oak.spi.state.NodeBuilder;
+import org.apache.jackrabbit.oak.spi.state.NodeState;
+import org.junit.Before;
+import org.junit.Test;
+import org.slf4j.LoggerFactory;
+
+import com.google.common.collect.ImmutableSet;
+
+import ch.qos.logback.classic.Level;
+import ch.qos.logback.classic.Logger;
+import ch.qos.logback.classic.LoggerContext;
+import ch.qos.logback.classic.spi.ILoggingEvent;
+import ch.qos.logback.core.Appender;
+import ch.qos.logback.core.read.ListAppender;
+import ch.qos.logback.core.spi.FilterReply;
+
+/**
+ * Test the Property2 index mechanism.
+ */
+public class PropertyIndexDeprecatedTest {
+
+    private static final int MANY = 100;
+
+    private NodeState root;
+    private NodeBuilder rootBuilder;
+    private static final EditorHook HOOK = new EditorHook(
+            new IndexUpdateProvider(new PropertyIndexEditorProvider()));
+ 
+    @Before
+    public void setup() throws Exception {
+        root = EmptyNodeState.EMPTY_NODE;
+        rootBuilder = InitialContentHelper.INITIAL_CONTENT.builder();
+        commit();
+    }
+
+    @Test
+    public void deprecated() throws Exception {
+        NodeBuilder index = createIndexDefinition(rootBuilder.child(INDEX_DEFINITIONS_NAME), 
+                "foo", true, false, ImmutableSet.of("foo"), null);
+        index.setProperty(IndexConstants.INDEX_DEPRECATED, false);
+        commit();
+        for (int i = 0; i < MANY; i++) {
+            rootBuilder.child("test").child("n" + i).setProperty("foo", "x" + i % 20);
+        }
+        commit();
+        
+        FilterImpl f = createFilter(root, NT_BASE);
+        f.restrictProperty("foo", Operator.EQUAL, PropertyValues.newString("x10"));
+        PropertyIndex propertyIndex = new PropertyIndex(Mounts.defaultMountInfoProvider());
+        assertTrue(propertyIndex.getCost(f, root) != Double.POSITIVE_INFINITY);
+        ListAppender<ILoggingEvent> appender = createAndRegisterAppender();
+        propertyIndex.query(f, root);
+        
+        assertEquals("[]", appender.list.toString());
+        appender.list.clear();
+        
+        // now test with a node that doesn't exist
+        index = rootBuilder.child(INDEX_DEFINITIONS_NAME).child("foo");
+        index.setProperty(IndexConstants.INDEX_DEPRECATED, true);
+        commit();
+        
+        appender.list.clear();
+        // need to create a new one - otherwise the cached definition is used
+        propertyIndex = new PropertyIndex(Mounts.defaultMountInfoProvider());
+        propertyIndex.query(f, root);
+        assertEquals("[[WARN] This index is deprecated: foo; " + 
+                "it is used for query Filter(query=" + 
+                "SELECT * FROM [nt:base], path=*, property=[foo=[x10]]). " + 
+                "Please change the query or the index definitions.]", appender.list.toString());
+        
+        index = rootBuilder.child(INDEX_DEFINITIONS_NAME).child("foo");
+        index.removeProperty(IndexConstants.INDEX_DEPRECATED);
+        commit();
+
+        appender.list.clear();
+        // need to create a new one - otherwise the cached definition is used
+        propertyIndex = new PropertyIndex(Mounts.defaultMountInfoProvider());
+        propertyIndex.query(f, root);
+        assertEquals("[]", appender.list.toString());
+
+        deregisterAppender(appender);
+    }
+    
+    private void commit() throws Exception {
+        root = HOOK.processCommit(rootBuilder.getBaseState(), rootBuilder.getNodeState(), EMPTY);
+        rootBuilder = root.builder();
+    }
+
+    private static FilterImpl createFilter(NodeState root, String nodeTypeName) {
+        NodeTypeInfoProvider nodeTypes = new NodeStateNodeTypeInfoProvider(root);
+        NodeTypeInfo type = nodeTypes.getNodeTypeInfo(nodeTypeName);        
+        SelectorImpl selector = new SelectorImpl(type, nodeTypeName);
+        return new FilterImpl(selector, "SELECT * FROM [" + nodeTypeName + "]", new QueryEngineSettings());
+    }
+    
+    private ListAppender<ILoggingEvent> createAndRegisterAppender() {
+        WarnFilter filter = new WarnFilter();
+        filter.start();        
+        ListAppender<ILoggingEvent> appender = new ListAppender<>();
+        appender.setContext(getContext());
+        appender.setName("TestLogCollector");
+        appender.addFilter(filter);        
+        appender.start();
+        rootLogger().addAppender(appender);
+        return appender;
+    }    
+    
+    private void deregisterAppender(Appender<ILoggingEvent> appender){
+        rootLogger().detachAppender(appender);
+    }
+    
+    private static class WarnFilter extends ch.qos.logback.core.filter.Filter<ILoggingEvent> {
+
+        @Override
+        public FilterReply decide(ILoggingEvent event) {
+            if (event.getLevel().isGreaterOrEqual(Level.WARN)) {
+                return FilterReply.ACCEPT;
+            } else {
+                return FilterReply.DENY;
+            }
+        }
+    }    
+    
+    private static LoggerContext getContext(){
+        return (LoggerContext) LoggerFactory.getILoggerFactory();
+    }
+    
+    private static ch.qos.logback.classic.Logger rootLogger() {
+        return getContext().getLogger(ch.qos.logback.classic.Logger.ROOT_LOGGER_NAME);
+    }    
+    
+    public void startCollecting() {
+        Logger fooLogger = (Logger) LoggerFactory.getLogger(PropertyIndexDeprecatedTest.class);        
+        ListAppender<ILoggingEvent> listAppender = new ListAppender<>();
+        listAppender.start();
+
+        // add the appender to the logger
+        fooLogger.addAppender(listAppender);
+        
+        fooLogger.warn("hello");
+        
+        List<ILoggingEvent> logsList = listAppender.list;
+        System.out.println(logsList);
+        
+    }
+
+}

Modified: jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/index/property/PropertyIndexDisabledTest.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/index/property/PropertyIndexDisabledTest.java?rev=1841340&r1=1841339&r2=1841340&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/index/property/PropertyIndexDisabledTest.java (original)
+++ jackrabbit/oak/trunk/oak-core/src/test/java/org/apache/jackrabbit/oak/plugins/index/property/PropertyIndexDisabledTest.java Wed Sep 19 13:53:44 2018
@@ -16,44 +16,17 @@
  */
 package org.apache.jackrabbit.oak.plugins.index.property;
 
-import static com.google.common.collect.ImmutableSet.of;
-import static org.apache.jackrabbit.JcrConstants.JCR_PRIMARYTYPE;
 import static org.apache.jackrabbit.JcrConstants.NT_BASE;
-import static org.apache.jackrabbit.JcrConstants.NT_FILE;
-import static org.apache.jackrabbit.JcrConstants.NT_UNSTRUCTURED;
-import static org.apache.jackrabbit.oak.plugins.index.IndexConstants.DECLARING_NODE_TYPES;
-import static org.apache.jackrabbit.oak.plugins.index.IndexConstants.INDEX_CONTENT_NODE_NAME;
 import static org.apache.jackrabbit.oak.plugins.index.IndexConstants.INDEX_DEFINITIONS_NAME;
 import static org.apache.jackrabbit.oak.plugins.index.IndexUtils.createIndexDefinition;
-import static org.apache.jackrabbit.oak.plugins.index.counter.NodeCounterEditor.COUNT_PROPERTY_NAME;
-import static org.apache.jackrabbit.oak.plugins.memory.EmptyNodeState.EMPTY_NODE;
-import static org.apache.jackrabbit.oak.plugins.memory.PropertyStates.createProperty;
-import static org.apache.jackrabbit.oak.InitialContentHelper.INITIAL_CONTENT;
-import static org.apache.jackrabbit.oak.api.Type.NAMES;
 import static org.apache.jackrabbit.oak.spi.commit.CommitInfo.EMPTY;
-import static org.apache.jackrabbit.oak.spi.filter.PathFilter.PROP_EXCLUDED_PATHS;
-import static org.apache.jackrabbit.oak.spi.filter.PathFilter.PROP_INCLUDED_PATHS;
-import static org.apache.jackrabbit.oak.spi.state.NodeStateUtils.getNode;
 import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertTrue;
-import static org.junit.Assert.fail;
-
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Set;
 
 import org.apache.jackrabbit.oak.InitialContentHelper;
-import org.apache.jackrabbit.oak.api.CommitFailedException;
-import org.apache.jackrabbit.oak.api.PropertyState;
-import org.apache.jackrabbit.oak.api.PropertyValue;
-import org.apache.jackrabbit.oak.api.Type;
-import org.apache.jackrabbit.oak.commons.PathUtils;
 import org.apache.jackrabbit.oak.plugins.index.IndexConstants;
 import org.apache.jackrabbit.oak.plugins.index.IndexUpdateProvider;
-import org.apache.jackrabbit.oak.plugins.index.property.strategy.ContentMirrorStoreStrategy;
 import org.apache.jackrabbit.oak.plugins.memory.EmptyNodeState;
-import org.apache.jackrabbit.oak.plugins.memory.PropertyStates;
 import org.apache.jackrabbit.oak.plugins.memory.PropertyValues;
 import org.apache.jackrabbit.oak.query.NodeStateNodeTypeInfoProvider;
 import org.apache.jackrabbit.oak.query.QueryEngineSettings;
@@ -62,33 +35,14 @@ import org.apache.jackrabbit.oak.query.a
 import org.apache.jackrabbit.oak.query.ast.Operator;
 import org.apache.jackrabbit.oak.query.ast.SelectorImpl;
 import org.apache.jackrabbit.oak.query.index.FilterImpl;
-import org.apache.jackrabbit.oak.query.index.TraversingIndex;
-import org.apache.jackrabbit.oak.spi.commit.CommitInfo;
-import org.apache.jackrabbit.oak.spi.commit.CompositeHook;
-import org.apache.jackrabbit.oak.spi.commit.DefaultValidator;
 import org.apache.jackrabbit.oak.spi.commit.EditorHook;
-import org.apache.jackrabbit.oak.spi.commit.Validator;
-import org.apache.jackrabbit.oak.spi.commit.ValidatorProvider;
-import org.apache.jackrabbit.oak.spi.mount.Mount;
-import org.apache.jackrabbit.oak.spi.mount.MountInfoProvider;
 import org.apache.jackrabbit.oak.spi.mount.Mounts;
-import org.apache.jackrabbit.oak.spi.query.Filter;
 import org.apache.jackrabbit.oak.spi.state.NodeBuilder;
 import org.apache.jackrabbit.oak.spi.state.NodeState;
 import org.junit.Before;
 import org.junit.Test;
-import org.slf4j.LoggerFactory;
-
-import ch.qos.logback.classic.Level;
-import ch.qos.logback.classic.LoggerContext;
-import ch.qos.logback.classic.spi.ILoggingEvent;
-import ch.qos.logback.core.Appender;
-import ch.qos.logback.core.read.ListAppender;
-import ch.qos.logback.core.spi.FilterReply;
 
 import com.google.common.collect.ImmutableSet;
-import com.google.common.collect.Iterables;
-import com.google.common.collect.Sets;
 
 /**
  * Test the Property2 index mechanism.

Modified: jackrabbit/oak/trunk/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/IndexDefinition.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/IndexDefinition.java?rev=1841340&r1=1841339&r2=1841340&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/IndexDefinition.java (original)
+++ jackrabbit/oak/trunk/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/IndexDefinition.java Wed Sep 19 13:53:44 2018
@@ -272,6 +272,8 @@ public final class IndexDefinition imple
 
     private final String useIfExists;
 
+    private final boolean deprecated;
+
     //~--------------------------------------------------------< Builder >
 
     public static Builder newBuilder(NodeState root, NodeState defn, String indexPath){
@@ -411,6 +413,7 @@ public final class IndexDefinition imple
         this.syncIndexMode = supportsSyncIndexing(defn);
         this.syncPropertyIndexes = definedRules.stream().anyMatch(ir -> !ir.syncProps.isEmpty());
         this.useIfExists = getOptionalValue(defn, IndexConstants.USE_IF_EXISTS, null);
+        this.deprecated = getOptionalValue(defn, IndexConstants.INDEX_DEPRECATED, false);
     }
 
     public NodeState getDefinitionNodeState() {
@@ -483,6 +486,10 @@ public final class IndexDefinition imple
         return costPerExecution;
     }
 
+    public boolean isDeprecated() {
+        return deprecated;
+    }
+
     public long getFulltextEntryCount(long numOfDocs){
         if (isEntryCountDefined()){
             return Math.min(getEntryCount(), numOfDocs);

Modified: jackrabbit/oak/trunk/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/LuceneIndex.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/LuceneIndex.java?rev=1841340&r1=1841339&r2=1841340&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/LuceneIndex.java (original)
+++ jackrabbit/oak/trunk/oak-lucene/src/main/java/org/apache/jackrabbit/oak/plugins/index/lucene/LuceneIndex.java Wed Sep 19 13:53:44 2018
@@ -215,6 +215,7 @@ public class LuceneIndex implements Adva
                         .setCostPerExecution(defn.getCostPerExecution())
                         .setCostPerEntry(defn.getCostPerEntry())
                         .setAttribute(ATTR_INDEX_PATH, indexPath)
+                        .setDeprecated(defn.isDeprecated())
                         .build());
             }
             //No index node then no plan possible

Modified: jackrabbit/oak/trunk/oak-query-spi/src/main/java/org/apache/jackrabbit/oak/spi/query/QueryIndex.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-query-spi/src/main/java/org/apache/jackrabbit/oak/spi/query/QueryIndex.java?rev=1841340&r1=1841339&r2=1841340&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-query-spi/src/main/java/org/apache/jackrabbit/oak/spi/query/QueryIndex.java (original)
+++ jackrabbit/oak/trunk/oak-query-spi/src/main/java/org/apache/jackrabbit/oak/spi/query/QueryIndex.java Wed Sep 19 13:53:44 2018
@@ -77,7 +77,7 @@ public interface QueryIndex {
      * <p>
      * If an index implementation can not query the data, it has to return
      * {@code Double.MAX_VALUE}.
-     * 
+     *
      * @param filter the filter
      * @param rootState root state of the current repository snapshot
      * @return the estimated cost in number of read nodes
@@ -99,7 +99,7 @@ public interface QueryIndex {
      * filter, then this method is not called. If it is still called, then it is
      * supposed to throw an exception (as it would be an internal error of the
      * query engine).
-     * 
+     *
      * @param filter the filter
      * @param rootState root state of the current repository snapshot
      * @return a cursor to iterate over the result
@@ -110,7 +110,7 @@ public interface QueryIndex {
      * Get the query plan for the given filter. This method is called when
      * running an {@code EXPLAIN SELECT} query, or for logging purposes. The
      * result should be human readable.
-     * 
+     *
      * @param filter the filter
      * @param rootState root state of the current repository snapshot
      * @return the query plan
@@ -142,7 +142,7 @@ public interface QueryIndex {
         /**
          * Returns the NodeAggregator responsible for providing the aggregation
          * settings or null if aggregation is not available/desired.
-         * 
+         *
          * @return the node aggregator or null
          */
         @Nullable
@@ -165,7 +165,7 @@ public interface QueryIndex {
          * Return the possible index plans for the given filter and sort order.
          * Please note this method is supposed to run quickly. That means it
          * should usually not read any data from the storage.
-         * 
+         *
          * @param filter the filter
          * @param sortOrder the sort order or null if no sorting is required
          * @param rootState root state of the current repository snapshot
@@ -179,7 +179,7 @@ public interface QueryIndex {
          * <p>
          * The index plan is one of the plans that the index returned in the
          * getPlans call.
-         * 
+         *
          * @param plan the index plan
          * @param root root state of the current repository snapshot
          * @return the query plan description
@@ -192,7 +192,7 @@ public interface QueryIndex {
          * <p>
          * The index plan is one of the plans that the index returned in the
          * getPlans call.
-         * 
+         *
          * @param plan the index plan to use
          * @param rootState root state of the current repository snapshot
          * @return a cursor to iterate over the result
@@ -211,7 +211,7 @@ public interface QueryIndex {
          * The cost to execute the query once. The returned value should
          * approximately match the number of disk read operations plus the
          * number of network roundtrips (worst case).
-         * 
+         *
          * @return the cost per execution, in estimated number of I/O operations
          */
         double getCostPerExecution();
@@ -220,7 +220,7 @@ public interface QueryIndex {
          * The cost to read one entry from the cursor. The returned value should
          * approximately match the number of disk read operations plus the
          * number of network roundtrips (worst case).
-         * 
+         *
          * @return the lookup cost per entry, in estimated number of I/O operations
          */
         double getCostPerEntry();
@@ -228,18 +228,18 @@ public interface QueryIndex {
         /**
          * The estimated number of entries in the cursor that is returned by the query method,
          * when using this plan. This value does not have to be accurate.
-         * 
+         *
          * @return the estimated number of entries
          */
         long getEstimatedEntryCount();
 
         /**
          * The filter to use.
-         * 
+         *
          * @return the filter
          */
         Filter getFilter();
-        
+
         /**
          * Use the given filter.
          */
@@ -247,7 +247,7 @@ public interface QueryIndex {
 
         /**
          * Whether the index is not always up-to-date.
-         * 
+         *
          * @return whether the index might be updated asynchronously
          */
         boolean isDelayed();
@@ -256,7 +256,7 @@ public interface QueryIndex {
          * Whether the fulltext part of the filter is evaluated (possibly with
          * an extended syntax). If set, the fulltext part of the filter is not
          * evaluated any more within the query engine.
-         * 
+         *
          * @return whether the index supports full-text extraction
          */
         boolean isFulltextIndex();
@@ -264,14 +264,14 @@ public interface QueryIndex {
         /**
          * Whether the cursor is able to read all properties from a node.
          * If yes, then the query engine will not have to read the data itself.
-         * 
+         *
          * @return wheter node data is returned
          */
         boolean includesNodeData();
 
         /**
          * The sort order of the returned entries, or null if unsorted.
-         * 
+         *
          * @return the sort order
          */
         List<OrderEntry> getSortOrder();
@@ -333,6 +333,13 @@ public interface QueryIndex {
         String getPlanName();
 
         /**
+         * Whether the index is deprecated.
+         *
+         * @return if it is deprecated
+         */
+        boolean isDeprecated();
+
+        /**
          * A builder for index plans.
          */
         class Builder {
@@ -351,6 +358,7 @@ public interface QueryIndex {
             protected boolean supportsPathRestriction = false;
             protected Map<String, Object> attributes = Maps.newHashMap();
             protected String planName;
+            protected boolean deprecated;
 
             public Builder setCostPerExecution(double costPerExecution) {
                 this.costPerExecution = costPerExecution;
@@ -422,25 +430,30 @@ public interface QueryIndex {
                 return this;
              }
 
+            public Builder setDeprecated(boolean deprecated) {
+                this.deprecated = deprecated;
+                return this;
+            }
+
             public IndexPlan build() {
-                
+
                 return new IndexPlan() {
-                    
-                    private final double costPerExecution = 
+
+                    private final double costPerExecution =
                             Builder.this.costPerExecution;
-                    private final double costPerEntry = 
+                    private final double costPerEntry =
                             Builder.this.costPerEntry;
-                    private final long estimatedEntryCount = 
+                    private final long estimatedEntryCount =
                             Builder.this.estimatedEntryCount;
-                    private Filter filter = 
+                    private Filter filter =
                             Builder.this.filter;
-                    private final boolean isDelayed = 
+                    private final boolean isDelayed =
                             Builder.this.isDelayed;
-                    private final boolean isFulltextIndex = 
+                    private final boolean isFulltextIndex =
                             Builder.this.isFulltextIndex;
-                    private final boolean includesNodeData = 
+                    private final boolean includesNodeData =
                             Builder.this.includesNodeData;
-                    private final List<OrderEntry> sortOrder = 
+                    private final List<OrderEntry> sortOrder =
                             Builder.this.sortOrder == null ?
                             null : new ArrayList<OrderEntry>(
                                     Builder.this.sortOrder);
@@ -455,6 +468,8 @@ public interface QueryIndex {
                     private final Map<String, Object> attributes =
                             Builder.this.attributes;
                     private final String planName = Builder.this.planName;
+                    private final boolean deprecated =
+                            Builder.this.deprecated;
 
                     @Override
                     public String toString() {
@@ -470,6 +485,7 @@ public interface QueryIndex {
                             + " definition : %s,"
                             + " propertyRestriction : %s,"
                             + " pathPrefix : %s,"
+                            + " deprecated : %s,"
                             + " supportsPathRestriction : %s }",
                             costPerExecution,
                             costPerEntry,
@@ -482,6 +498,7 @@ public interface QueryIndex {
                             definition,
                             propRestriction,
                             pathPrefix,
+                            deprecated,
                             supportsPathRestriction
                             );
                     }
@@ -505,7 +522,7 @@ public interface QueryIndex {
                     public Filter getFilter() {
                         return filter;
                     }
-                    
+
                     @Override
                     public void setFilter(Filter filter) {
                         this.filter = filter;
@@ -574,6 +591,12 @@ public interface QueryIndex {
                     public String getPlanName() {
                         return planName;
                     }
+
+                    @Override
+                    public boolean isDeprecated() {
+                        return deprecated;
+                    }
+
                 };
             }
 
@@ -590,19 +613,19 @@ public interface QueryIndex {
          * The property name on where to sort.
          */
         private final String propertyName;
-        
+
         /**
          * The property type. Null if not known.
          */
         private final Type<?> propertyType;
-        
+
         /**
          * The sort order (ascending or descending).
          */
         public enum Order { ASCENDING, DESCENDING }
-        
+
         private final Order order;
-        
+
         public OrderEntry(String propertyName, Type<?> propertyType, Order order) {
             this.propertyName = propertyName;
             this.propertyType = propertyType;

Modified: jackrabbit/oak/trunk/oak-query-spi/src/main/java/org/apache/jackrabbit/oak/spi/query/package-info.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-query-spi/src/main/java/org/apache/jackrabbit/oak/spi/query/package-info.java?rev=1841340&r1=1841339&r2=1841340&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-query-spi/src/main/java/org/apache/jackrabbit/oak/spi/query/package-info.java (original)
+++ jackrabbit/oak/trunk/oak-query-spi/src/main/java/org/apache/jackrabbit/oak/spi/query/package-info.java Wed Sep 19 13:53:44 2018
@@ -14,7 +14,7 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-@Version("1.0.1")
+@Version("1.1.0")
 package org.apache.jackrabbit.oak.spi.query;
 
 import org.osgi.annotation.versioning.Version;