[NO ISSUE][COMP] Introduce Index Only Compiler Property

- user model changes: no
- storage format changes: no
- interface changes: no

Details:
- Introduce "compiler.indexonly" compiler property to
  enable/disable index-only plans.
- Replace usage of 'noindexonly' query property by
  the new compiler property.
- Update docs and test cases.

Change-Id: I82d05bbfacbaca17eb8d8a2b6d825aa180e9ab02
Reviewed-on: https://asterix-gerrit.ics.uci.edu/c/asterixdb/+/5567
Contrib: Jenkins <jenkins@fulliautomatix.ics.uci.edu>
Integration-Tests: Jenkins <jenkins@fulliautomatix.ics.uci.edu>
Tested-by: Jenkins <jenkins@fulliautomatix.ics.uci.edu>
Reviewed-by: Murtadha Hubail <mhubail@apache.org>
Reviewed-by: Dmitry Lychagin <dmitry.lychagin@couchbase.com>
diff --git a/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/am/AbstractIntroduceAccessMethodRule.java b/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/am/AbstractIntroduceAccessMethodRule.java
index c45ad6d..48b027c 100644
--- a/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/am/AbstractIntroduceAccessMethodRule.java
+++ b/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/am/AbstractIntroduceAccessMethodRule.java
@@ -87,9 +87,6 @@
  * methods.
  */
 public abstract class AbstractIntroduceAccessMethodRule implements IAlgebraicRewriteRule {
-    // When this option is set to true before executing a query, we don't apply the index-only plan.
-    public final static String NO_INDEX_ONLY_PLAN_OPTION = "noindexonly";
-    public final static boolean NO_INDEX_ONLY_PLAN_OPTION_DEFAULT_VALUE = false;
 
     protected MetadataProvider metadataProvider;
 
diff --git a/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/am/AccessMethodUtils.java b/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/am/AccessMethodUtils.java
index 38072f3..dc83fb1 100644
--- a/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/am/AccessMethodUtils.java
+++ b/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/am/AccessMethodUtils.java
@@ -25,7 +25,6 @@
 import java.util.Iterator;
 import java.util.LinkedHashMap;
 import java.util.List;
-import java.util.Map;
 import java.util.Set;
 
 import org.apache.asterix.algebra.operators.physical.ExternalDataLookupPOperator;
@@ -1887,7 +1886,7 @@
         // may not be equal to the actual value in the record. (e.g., INT index and BIGINT value in the actual record)
         // Since index-only plan doesn't access the primary index, we can't get the actual value in this case.
         // Also, if no-index-only option is given, we stop here to honor that request.
-        boolean noIndexOnlyPlanOption = getNoIndexOnlyOption(context);
+        boolean noIndexOnlyPlanOption = !context.getPhysicalOptimizationConfig().isIndexOnly();
         // TODO: For the inverted index access-method cases only:
         // Since an inverted index can contain multiple secondary key entries per one primary key,
         // Index-only plan can't be applied. For example, suppose there are two entries (SK1, SK2) for one PK.
@@ -1898,9 +1897,9 @@
         // Even if the above is resolved, if a secondary key field is used after
         // SELECT or JOIN operator, this can't be qualified as an index-only plan since
         // an inverted index contains a part of a field value, not all of it.
-        if (dataset.getDatasetType() == DatasetType.EXTERNAL || chosenIndex.isPrimaryIndex()
-                || chosenIndex.isOverridingKeyFieldTypes() || chosenIndex.isEnforced() || isInvertedIndex(chosenIndex)
-                || noIndexOnlyPlanOption) {
+        if (noIndexOnlyPlanOption || dataset.getDatasetType() == DatasetType.EXTERNAL || chosenIndex.isPrimaryIndex()
+                || chosenIndex.isOverridingKeyFieldTypes() || chosenIndex.isEnforced()
+                || isInvertedIndex(chosenIndex)) {
             indexOnlyPlanInfo.setFirst(false);
             return;
         }
@@ -2650,22 +2649,6 @@
     }
 
     /**
-     * Gets the specified no-index-only option in a query.
-     *
-     * @param context
-     * @return true if no-index-only plan is true.
-     *         false otherwise.
-     */
-    public static boolean getNoIndexOnlyOption(IOptimizationContext context) {
-        Map<String, Object> config = context.getMetadataProvider().getConfig();
-        if (config.containsKey(AbstractIntroduceAccessMethodRule.NO_INDEX_ONLY_PLAN_OPTION)) {
-            return Boolean
-                    .parseBoolean((String) config.get(AbstractIntroduceAccessMethodRule.NO_INDEX_ONLY_PLAN_OPTION));
-        }
-        return AbstractIntroduceAccessMethodRule.NO_INDEX_ONLY_PLAN_OPTION_DEFAULT_VALUE;
-    }
-
-    /**
      * Finds an output variable for the given input variable of UnionAllOperator.
      */
     static LogicalVariable findUnionAllOutputVariable(UnionAllOperator unionAllOp, LogicalVariable inputVar) {
diff --git a/asterixdb/asterix-app/src/main/java/org/apache/asterix/api/common/APIFramework.java b/asterixdb/asterix-app/src/main/java/org/apache/asterix/api/common/APIFramework.java
index d573b52..a3593d5 100644
--- a/asterixdb/asterix-app/src/main/java/org/apache/asterix/api/common/APIFramework.java
+++ b/asterixdb/asterix-app/src/main/java/org/apache/asterix/api/common/APIFramework.java
@@ -72,7 +72,6 @@
 import org.apache.asterix.optimizer.base.AsterixOptimizationContext;
 import org.apache.asterix.optimizer.base.FuzzyUtils;
 import org.apache.asterix.optimizer.rules.DisjunctivePredicateToJoinRule;
-import org.apache.asterix.optimizer.rules.am.AbstractIntroduceAccessMethodRule;
 import org.apache.asterix.runtime.job.listener.JobEventListenerFactory;
 import org.apache.asterix.translator.CompiledStatements.ICompiledDmlStatement;
 import org.apache.asterix.translator.ExecutionPlans;
@@ -134,11 +133,11 @@
                     CompilerProperties.COMPILER_SORTMEMORY_KEY, CompilerProperties.COMPILER_WINDOWMEMORY_KEY,
                     CompilerProperties.COMPILER_TEXTSEARCHMEMORY_KEY, CompilerProperties.COMPILER_PARALLELISM_KEY,
                     CompilerProperties.COMPILER_SORT_PARALLEL_KEY, CompilerProperties.COMPILER_SORT_SAMPLES_KEY,
-                    FunctionUtil.IMPORT_PRIVATE_FUNCTIONS, FuzzyUtils.SIM_FUNCTION_PROP_NAME,
-                    FuzzyUtils.SIM_THRESHOLD_PROP_NAME, StartFeedStatement.WAIT_FOR_COMPLETION,
-                    FeedActivityDetails.FEED_POLICY_NAME, FeedActivityDetails.COLLECT_LOCATIONS,
-                    SqlppQueryRewriter.INLINE_WITH_OPTION, SqlppExpressionToPlanTranslator.REWRITE_IN_AS_OR_OPTION,
-                    "hash_merge", "output-record-type", AbstractIntroduceAccessMethodRule.NO_INDEX_ONLY_PLAN_OPTION,
+                    CompilerProperties.COMPILER_INDEXONLY_KEY, FunctionUtil.IMPORT_PRIVATE_FUNCTIONS,
+                    FuzzyUtils.SIM_FUNCTION_PROP_NAME, FuzzyUtils.SIM_THRESHOLD_PROP_NAME,
+                    StartFeedStatement.WAIT_FOR_COMPLETION, FeedActivityDetails.FEED_POLICY_NAME,
+                    FeedActivityDetails.COLLECT_LOCATIONS, SqlppQueryRewriter.INLINE_WITH_OPTION,
+                    SqlppExpressionToPlanTranslator.REWRITE_IN_AS_OR_OPTION, "hash_merge", "output-record-type",
                     DisjunctivePredicateToJoinRule.REWRITE_OR_AS_JOIN_OPTION);
 
     private final IRewriterFactory rewriterFactory;
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/queries/btree-index-join/leftouterjoin-probe-pidx-with-join-btree-sidx_01.aql b/asterixdb/asterix-app/src/test/resources/optimizerts/queries/btree-index-join/leftouterjoin-probe-pidx-with-join-btree-sidx_01.aql
index 71e94e2..784bf90 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/queries/btree-index-join/leftouterjoin-probe-pidx-with-join-btree-sidx_01.aql
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/queries/btree-index-join/leftouterjoin-probe-pidx-with-join-btree-sidx_01.aql
@@ -56,7 +56,7 @@
 create index msgCountBIx on TweetMessages(countB) type btree;
 create index msgTextIx on TweetMessages(message-text) type keyword;
 
-set noindexonly 'true';
+set 'compiler.indexonly' "false";
 
 for $t1 in dataset('TweetMessages')
 where $t1.tweetid < int64("10")
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/queries/btree-index-join/leftouterjoin-probe-pidx-with-join-btree-sidx_03-index-only.sqlpp b/asterixdb/asterix-app/src/test/resources/optimizerts/queries/btree-index-join/leftouterjoin-probe-pidx-with-join-btree-sidx_03-index-only.sqlpp
index e693b46..9da4825 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/queries/btree-index-join/leftouterjoin-probe-pidx-with-join-btree-sidx_03-index-only.sqlpp
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/queries/btree-index-join/leftouterjoin-probe-pidx-with-join-btree-sidx_03-index-only.sqlpp
@@ -61,7 +61,7 @@
 
 create  index msgTextIx  on TweetMessages (`message-text`) type keyword;
 
-set noindexonly "false";
+set `compiler.indexonly` "true";
 
 select t1.tweetid as tweetid1, t1.countA as count1, t2.tweetid as tweetid2, t2.countB as count2
 from  TweetMessages as t1 left outer join TweetMessages as t2 on t1.countA /*+ indexnl */ = t2.countB
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/queries/btree-index-join/leftouterjoin-probe-pidx-with-join-btree-sidx_03.sqlpp b/asterixdb/asterix-app/src/test/resources/optimizerts/queries/btree-index-join/leftouterjoin-probe-pidx-with-join-btree-sidx_03.sqlpp
index 24a84dc..6e972e6 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/queries/btree-index-join/leftouterjoin-probe-pidx-with-join-btree-sidx_03.sqlpp
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/queries/btree-index-join/leftouterjoin-probe-pidx-with-join-btree-sidx_03.sqlpp
@@ -61,7 +61,7 @@
 
 create  index msgTextIx  on TweetMessages (`message-text`) type keyword;
 
-set noindexonly "true";
+set `compiler.indexonly` "false";
 
 select t1.tweetid as tweetid1, t1.countA as count1, t2.tweetid as tweetid2, t2.countB as count2
 from  TweetMessages as t1 left outer join TweetMessages as t2 on t1.countA /*+ indexnl */ = t2.countB
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/queries/btree-index-join/secondary-self-equi-join.aql b/asterixdb/asterix-app/src/test/resources/optimizerts/queries/btree-index-join/secondary-self-equi-join.aql
index 74f2d87..7dd9ddb 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/queries/btree-index-join/secondary-self-equi-join.aql
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/queries/btree-index-join/secondary-self-equi-join.aql
@@ -55,7 +55,7 @@
 create index msgCountBIx on TweetMessages(countB) type btree;
 create index msgTextIx on TweetMessages(message-text) type keyword;
 
-set noindexonly 'true';
+set 'compiler.indexonly' "false";
 
 for $t1 in dataset('TweetMessages')
 for $t2 in dataset('TweetMessages')
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/queries/btree-index/btree-sidx-idxonly-01-disable-idxonly.sqlpp b/asterixdb/asterix-app/src/test/resources/optimizerts/queries/btree-index/btree-sidx-idxonly-01-disable-idxonly.sqlpp
index 0be684e..d45a7eb 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/queries/btree-index/btree-sidx-idxonly-01-disable-idxonly.sqlpp
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/queries/btree-index/btree-sidx-idxonly-01-disable-idxonly.sqlpp
@@ -26,7 +26,7 @@
  *                      ... -> unnest-map (sidx) -> split -> unnest-map (pidx) -> select -> union -> ...
  *                  : The right path:
  *                      ... -> unnest-map (sidx) -> split ->                             -> union -> ...
- *                  : However, we set the "noindexonly" option to true. So, the index-only plan should not be triggered.
+ *                  : However, we set the `compiler.indexonly` option to false. So, the index-only plan should not be triggered.
  *  Expected Result : Success
  *
 */
@@ -59,7 +59,7 @@
 create index ngram_index_title on MyData(title) type ngram(3);
 create index keyword_index_title on MyData(title) type keyword;
 
-set noindexonly 'true';
+set `compiler.indexonly` "false";
 
 select element {"pk":o.id, "sk":o.docid}
 from MyData o
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/queries/btree-index/btree-sidx-idxonly-01-disable-idxonly_ps.sqlpp b/asterixdb/asterix-app/src/test/resources/optimizerts/queries/btree-index/btree-sidx-idxonly-01-disable-idxonly_ps.sqlpp
index b986780..f7644cb 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/queries/btree-index/btree-sidx-idxonly-01-disable-idxonly_ps.sqlpp
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/queries/btree-index/btree-sidx-idxonly-01-disable-idxonly_ps.sqlpp
@@ -26,7 +26,7 @@
  *                      ... -> unnest-map (sidx) -> split -> unnest-map (pidx) -> select -> union -> ...
  *                  : The right path:
  *                      ... -> unnest-map (sidx) -> split ->                             -> union -> ...
- *                  : However, we set the "noindexonly" option to true. So, the index-only plan should not be triggered.
+ *                  : However, we set the `compiler.indexonly` option to false. So, the index-only plan should not be triggered.
  *  Expected Result : Success
  *
 */
@@ -59,7 +59,7 @@
 create index ngram_index_title on MyData(title) type ngram(3);
 create index keyword_index_title on MyData(title) type keyword;
 
-set noindexonly 'true';
+set `compiler.indexonly` "false";
 set `compiler.sort.parallel` "true";
 
 select element {"pk":o.id, "sk":o.docid}
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/queries/nested-index/rtree-index-join/leftouterjoin-probe-pidx-with-join-rtree-sidx_01.aql b/asterixdb/asterix-app/src/test/resources/optimizerts/queries/nested-index/rtree-index-join/leftouterjoin-probe-pidx-with-join-rtree-sidx_01.aql
index fbf8bd5..b4cf594 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/queries/nested-index/rtree-index-join/leftouterjoin-probe-pidx-with-join-rtree-sidx_01.aql
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/queries/nested-index/rtree-index-join/leftouterjoin-probe-pidx-with-join-rtree-sidx_01.aql
@@ -59,7 +59,7 @@
 create index msgCountBIx on TweetMessages(nested.countB) type btree;
 create index msgTextIx on TweetMessages(nested.message-text) type keyword;
 
-set noindexonly 'true';
+set 'compiler.indexonly' "false";
 
 for $t1 in dataset('TweetMessages')
 let $n :=  create-circle($t1.nested.sender-location, 0.5)
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/queries/nonpure/keep-datetime-local.aql b/asterixdb/asterix-app/src/test/resources/optimizerts/queries/nonpure/keep-datetime-local.aql
index c0f490c..840836a 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/queries/nonpure/keep-datetime-local.aql
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/queries/nonpure/keep-datetime-local.aql
@@ -56,7 +56,7 @@
 create index msgCountBIx on TweetMessages(countB) type btree;
 create index msgTextIx on TweetMessages(message-text) type keyword;
 
-set noindexonly 'true';
+set 'compiler.indexonly' "false";
 
 for $t1 in dataset('TweetMessages')
 let $time := current-datetime()
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/queries/orders-composite-index-search.aql b/asterixdb/asterix-app/src/test/resources/optimizerts/queries/orders-composite-index-search.aql
index 22d5b44..9fd94b3 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/queries/orders-composite-index-search.aql
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/queries/orders-composite-index-search.aql
@@ -36,7 +36,7 @@
 
 create index idx_Custkey_Orderstatus on Orders(o_custkey, o_orderstatus);
 
-set noindexonly 'true';
+set 'compiler.indexonly' "false";
 
 for $o in dataset('Orders')
 where
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/queries/orders-index-search-open.aql b/asterixdb/asterix-app/src/test/resources/optimizerts/queries/orders-index-search-open.aql
index 729b7e4..9547e6a 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/queries/orders-index-search-open.aql
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/queries/orders-index-search-open.aql
@@ -42,7 +42,7 @@
 
 create index idx_Orders_Custkey on Orders(o_custkey);
 
-set noindexonly 'true';
+set 'compiler.indexonly' "false";
 
 for $o in dataset('Orders')
 where
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/queries/orders-index-search.aql b/asterixdb/asterix-app/src/test/resources/optimizerts/queries/orders-index-search.aql
index ed8af00..3b49d9c 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/queries/orders-index-search.aql
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/queries/orders-index-search.aql
@@ -42,7 +42,7 @@
 
 create index idx_Orders_Custkey on Orders(o_custkey);
 
-set noindexonly 'true';
+set 'compiler.indexonly' "false";
 
 for $o in dataset('Orders')
 where
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/queries/rtree-index-join/issue730.aql b/asterixdb/asterix-app/src/test/resources/optimizerts/queries/rtree-index-join/issue730.aql
index c3f9cce..5d8d7e9 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/queries/rtree-index-join/issue730.aql
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/queries/rtree-index-join/issue730.aql
@@ -49,7 +49,7 @@
 
 create index twmSndLocIx on TweetMessages(sender_location) type rtree;
 
-set noindexonly 'true';
+set 'compiler.indexonly' "false";
 
 for $t1 in dataset('TweetMessages')
 where $t1.send_time >= datetime('2011-06-18T14:10:17') and $t1.send_time < datetime('2011-06-18T15:10:17')
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/queries/rtree-index-join/leftouterjoin-probe-pidx-with-join-rtree-sidx_01.aql b/asterixdb/asterix-app/src/test/resources/optimizerts/queries/rtree-index-join/leftouterjoin-probe-pidx-with-join-rtree-sidx_01.aql
index cf19dce..de11a36 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/queries/rtree-index-join/leftouterjoin-probe-pidx-with-join-rtree-sidx_01.aql
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/queries/rtree-index-join/leftouterjoin-probe-pidx-with-join-rtree-sidx_01.aql
@@ -56,7 +56,7 @@
 create index msgCountBIx on TweetMessages(countB) type btree;
 create index msgTextIx on TweetMessages(message-text) type keyword;
 
-set noindexonly 'true';
+set 'compiler.indexonly' "false";
 
 for $t1 in dataset('TweetMessages')
 let $n :=  create-circle($t1.sender-location, 0.5)
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/queries/rtree-index-join/spatial-self-intersect-point.aql b/asterixdb/asterix-app/src/test/resources/optimizerts/queries/rtree-index-join/spatial-self-intersect-point.aql
index 9a5eefa..473bc36 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/queries/rtree-index-join/spatial-self-intersect-point.aql
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/queries/rtree-index-join/spatial-self-intersect-point.aql
@@ -55,7 +55,7 @@
 create index msgCountBIx on TweetMessages(countB) type btree;
 create index msgTextIx on TweetMessages(message-text) type keyword;
 
-set noindexonly 'true';
+set 'compiler.indexonly' "false";
 
 for $t1 in dataset('TweetMessages')
 for $t2 in dataset('TweetMessages')
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/queries/rtree-index/rtree-sidx-idxonly-01-disable-idxonly.sqlpp b/asterixdb/asterix-app/src/test/resources/optimizerts/queries/rtree-index/rtree-sidx-idxonly-01-disable-idxonly.sqlpp
index dae4f0a..878ac9c 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/queries/rtree-index/rtree-sidx-idxonly-01-disable-idxonly.sqlpp
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/queries/rtree-index/rtree-sidx-idxonly-01-disable-idxonly.sqlpp
@@ -26,7 +26,7 @@
  *                      ... -> unnest-map (sidx) -> split -> unnest-map (pidx) -> select -> union -> ...
  *                  : The right path:
  *                      ... -> unnest-map (sidx) -> split ->                                union -> ...
- *                  : However, we set the "noindexonly" option to true. So, the index-only plan should not be triggered.
+ *                  : However, we set the `compiler.indexonly` option to false. So, the index-only plan should not be triggered.
  *  Expected Result : Success
  *
 */
@@ -105,7 +105,7 @@
 create index ngram_index_title on MyData(title) type ngram(3);
 create index keyword_index_title on MyData(title) type keyword;
 
-set noindexonly 'true';
+set `compiler.indexonly` "false";
 
 select count(*) from (
 select x.location
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/queries/rtree-secondary-index-open.aql b/asterixdb/asterix-app/src/test/resources/optimizerts/queries/rtree-secondary-index-open.aql
index 3372e64..a79face 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/queries/rtree-secondary-index-open.aql
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/queries/rtree-secondary-index-open.aql
@@ -43,7 +43,7 @@
 
 create index rtree_index_point on MyData(point) type rtree;
 
-set noindexonly 'true';
+set 'compiler.indexonly' "false";
 
 for $o in dataset('MyData')
 where spatial-intersect($o.point, create-polygon([4.0,1.0,4.0,4.0,12.0,4.0,12.0,1.0]))
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/queries/rtree-secondary-index.aql b/asterixdb/asterix-app/src/test/resources/optimizerts/queries/rtree-secondary-index.aql
index 84aad24..5636d16 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/queries/rtree-secondary-index.aql
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/queries/rtree-secondary-index.aql
@@ -43,7 +43,7 @@
 
 create index rtree_index_point on MyData(point) type rtree;
 
-set noindexonly 'true';
+set 'compiler.indexonly' "false";
 
 for $o in dataset('MyData')
 where spatial-intersect($o.point, create-polygon([4.0,1.0,4.0,4.0,12.0,4.0,12.0,1.0]))
diff --git a/asterixdb/asterix-app/src/test/resources/optimizerts/queries/udfs/query-ASTERIXDB-1019.aql b/asterixdb/asterix-app/src/test/resources/optimizerts/queries/udfs/query-ASTERIXDB-1019.aql
index ab6374a..6227eab 100644
--- a/asterixdb/asterix-app/src/test/resources/optimizerts/queries/udfs/query-ASTERIXDB-1019.aql
+++ b/asterixdb/asterix-app/src/test/resources/optimizerts/queries/udfs/query-ASTERIXDB-1019.aql
@@ -67,7 +67,7 @@
 create dataset NearbySheltersDuringTornadoDangerChannelResults(result)
 primary key id autogenerated;
 
-set noindexonly 'true';
+set 'compiler.indexonly' "false";
 
 insert into dataset NearbySheltersDuringTornadoDangerChannelResults (
 for $sub in dataset NearbySheltersDuringTornadoDangerChannelSubscriptions
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/index-leftouterjoin/probe-pidx-with-join-btree-sidx1/probe-pidx-with-join-btree-sidx1.4.query.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/index-leftouterjoin/probe-pidx-with-join-btree-sidx1/probe-pidx-with-join-btree-sidx1.4.query.sqlpp
index e1a91bc..0a84a67 100644
--- a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/index-leftouterjoin/probe-pidx-with-join-btree-sidx1/probe-pidx-with-join-btree-sidx1.4.query.sqlpp
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/index-leftouterjoin/probe-pidx-with-join-btree-sidx1/probe-pidx-with-join-btree-sidx1.4.query.sqlpp
@@ -24,7 +24,7 @@
 
 use test;
 
-set noindexonly "true";
+set `compiler.indexonly` "false";
 
 select t1.tweetid as tweetid1, t1.countA as count1, t2.tweetid as tweetid2, t2.countB as count2
 from  TweetMessages as t1 left outer join TweetMessages as t2 on t1.countA /*+ indexnl */ = t2.countB
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/index-leftouterjoin/probe-pidx-with-join-btree-sidx1/probe-pidx-with-join-btree-sidx1.5.query.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/index-leftouterjoin/probe-pidx-with-join-btree-sidx1/probe-pidx-with-join-btree-sidx1.5.query.sqlpp
index 6596c92..a312fe1 100644
--- a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/index-leftouterjoin/probe-pidx-with-join-btree-sidx1/probe-pidx-with-join-btree-sidx1.5.query.sqlpp
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/index-leftouterjoin/probe-pidx-with-join-btree-sidx1/probe-pidx-with-join-btree-sidx1.5.query.sqlpp
@@ -24,7 +24,7 @@
 
 use test;
 
-set noindexonly "false";
+set `compiler.indexonly` "false";
 
 select t1.tweetid as tweetid1, t1.countA as count1, t2.tweetid as tweetid2, t2.countB as count2
 from  TweetMessages as t1 left outer join TweetMessages as t2 on t1.countA /*+ indexnl */ = t2.countB
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/metrics/secondary-index/secondary-index.3.metrics.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/metrics/secondary-index/secondary-index.3.metrics.sqlpp
index 95d4681..98166d7 100644
--- a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/metrics/secondary-index/secondary-index.3.metrics.sqlpp
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/metrics/secondary-index/secondary-index.3.metrics.sqlpp
@@ -24,7 +24,7 @@
 
 use test;
 
-set noindexonly 'true';
+set `compiler.indexonly` "false";
 
 select count(*) from Customers
 where name = "Marvella Loud";
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/results/api/cluster_state_1/cluster_state_1.1.regexadm b/asterixdb/asterix-app/src/test/resources/runtimets/results/api/cluster_state_1/cluster_state_1.1.regexadm
index a23829f..acfc5e0 100644
--- a/asterixdb/asterix-app/src/test/resources/runtimets/results/api/cluster_state_1/cluster_state_1.1.regexadm
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/results/api/cluster_state_1/cluster_state_1.1.regexadm
@@ -10,6 +10,7 @@
     "active\.suspend\.timeout" : 3600,
     "compiler\.framesize" : 32768,
     "compiler\.groupmemory" : 163840,
+    "compiler\.indexonly" : true,
     "compiler\.joinmemory" : 262144,
     "compiler\.parallelism" : 0,
     "compiler\.sort\.parallel" : false,
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/results/api/cluster_state_1_full/cluster_state_1_full.1.regexadm b/asterixdb/asterix-app/src/test/resources/runtimets/results/api/cluster_state_1_full/cluster_state_1_full.1.regexadm
index 48e92b0..6d28223 100644
--- a/asterixdb/asterix-app/src/test/resources/runtimets/results/api/cluster_state_1_full/cluster_state_1_full.1.regexadm
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/results/api/cluster_state_1_full/cluster_state_1_full.1.regexadm
@@ -10,6 +10,7 @@
     "active\.suspend\.timeout" : 3600,
     "compiler\.framesize" : 32768,
     "compiler\.groupmemory" : 163840,
+    "compiler\.indexonly" : true,
     "compiler\.joinmemory" : 262144,
     "compiler\.parallelism" : -1,
     "compiler\.sort\.parallel" : true,
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/results/api/cluster_state_1_less/cluster_state_1_less.1.regexadm b/asterixdb/asterix-app/src/test/resources/runtimets/results/api/cluster_state_1_less/cluster_state_1_less.1.regexadm
index b631b8c..0724b25 100644
--- a/asterixdb/asterix-app/src/test/resources/runtimets/results/api/cluster_state_1_less/cluster_state_1_less.1.regexadm
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/results/api/cluster_state_1_less/cluster_state_1_less.1.regexadm
@@ -10,6 +10,7 @@
     "active\.suspend\.timeout" : 3600,
     "compiler\.framesize" : 32768,
     "compiler\.groupmemory" : 163840,
+    "compiler\.indexonly" : true,
     "compiler\.joinmemory" : 262144,
     "compiler\.parallelism" : 3,
     "compiler\.sort\.parallel" : true,
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/results_parser_sqlpp/index-leftouterjoin/probe-pidx-with-join-btree-sidx1/probe-pidx-with-join-btree-sidx1.4.ast b/asterixdb/asterix-app/src/test/resources/runtimets/results_parser_sqlpp/index-leftouterjoin/probe-pidx-with-join-btree-sidx1/probe-pidx-with-join-btree-sidx1.4.ast
index 4e1ebd6..a501d7f 100644
--- a/asterixdb/asterix-app/src/test/resources/runtimets/results_parser_sqlpp/index-leftouterjoin/probe-pidx-with-join-btree-sidx1/probe-pidx-with-join-btree-sidx1.4.ast
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/results_parser_sqlpp/index-leftouterjoin/probe-pidx-with-join-btree-sidx1/probe-pidx-with-join-btree-sidx1.4.ast
@@ -1,5 +1,5 @@
 DataverseUse test
-Set noindexonly=true
+Set compiler.indexonly=false
 Query:
 SELECT [
 FieldAccessor [
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/results_parser_sqlpp/index-leftouterjoin/probe-pidx-with-join-btree-sidx1/probe-pidx-with-join-btree-sidx1.5.ast b/asterixdb/asterix-app/src/test/resources/runtimets/results_parser_sqlpp/index-leftouterjoin/probe-pidx-with-join-btree-sidx1/probe-pidx-with-join-btree-sidx1.5.ast
index 965536d..a501d7f 100644
--- a/asterixdb/asterix-app/src/test/resources/runtimets/results_parser_sqlpp/index-leftouterjoin/probe-pidx-with-join-btree-sidx1/probe-pidx-with-join-btree-sidx1.5.ast
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/results_parser_sqlpp/index-leftouterjoin/probe-pidx-with-join-btree-sidx1/probe-pidx-with-join-btree-sidx1.5.ast
@@ -1,5 +1,5 @@
 DataverseUse test
-Set noindexonly=false
+Set compiler.indexonly=false
 Query:
 SELECT [
 FieldAccessor [
diff --git a/asterixdb/asterix-common/src/main/java/org/apache/asterix/common/config/CompilerProperties.java b/asterixdb/asterix-common/src/main/java/org/apache/asterix/common/config/CompilerProperties.java
index bdeaddb..b0c6472 100644
--- a/asterixdb/asterix-common/src/main/java/org/apache/asterix/common/config/CompilerProperties.java
+++ b/asterixdb/asterix-common/src/main/java/org/apache/asterix/common/config/CompilerProperties.java
@@ -71,7 +71,8 @@
         COMPILER_SORT_SAMPLES(
                 POSITIVE_INTEGER,
                 AlgebricksConfig.SORT_SAMPLES,
-                "The number of samples which parallel sorting should take from each partition");
+                "The number of samples which parallel sorting should take from each partition"),
+        COMPILER_INDEXONLY(BOOLEAN, AlgebricksConfig.INDEX_ONLY_DEFAULT, "Enabling/disabling index-only plans");
 
         private final IOptionType type;
         private final Object defaultValue;
@@ -120,6 +121,8 @@
 
     public static final String COMPILER_SORT_SAMPLES_KEY = Option.COMPILER_SORT_SAMPLES.ini();
 
+    public static final String COMPILER_INDEXONLY_KEY = Option.COMPILER_INDEXONLY.ini();
+
     public static final int COMPILER_PARALLELISM_AS_STORAGE = 0;
 
     public CompilerProperties(PropertiesAccessor accessor) {
@@ -161,4 +164,8 @@
     public int getSortSamples() {
         return accessor.getInt(Option.COMPILER_SORT_SAMPLES);
     }
+
+    public boolean isIndexOnly() {
+        return accessor.getBoolean(Option.COMPILER_INDEXONLY);
+    }
 }
diff --git a/asterixdb/asterix-common/src/main/java/org/apache/asterix/common/config/OptimizationConfUtil.java b/asterixdb/asterix-common/src/main/java/org/apache/asterix/common/config/OptimizationConfUtil.java
index 23fdcac..55f3f4f 100644
--- a/asterixdb/asterix-common/src/main/java/org/apache/asterix/common/config/OptimizationConfUtil.java
+++ b/asterixdb/asterix-common/src/main/java/org/apache/asterix/common/config/OptimizationConfUtil.java
@@ -59,6 +59,7 @@
         int textSearchFrameLimit = getTextSearchNumFrames(compilerProperties, querySpecificConfig, sourceLoc);
         int sortNumSamples = getSortSamples(compilerProperties, querySpecificConfig, sourceLoc);
         boolean fullParallelSort = getSortParallel(compilerProperties, querySpecificConfig);
+        boolean indexOnly = isIndexOnly(compilerProperties, querySpecificConfig);
 
         PhysicalOptimizationConfig physOptConf = new PhysicalOptimizationConfig();
         physOptConf.setFrameSize(frameSize);
@@ -69,7 +70,7 @@
         physOptConf.setMaxFramesForTextSearch(textSearchFrameLimit);
         physOptConf.setSortParallel(fullParallelSort);
         physOptConf.setSortSamples(sortNumSamples);
-
+        physOptConf.setIndexOnly(indexOnly);
         return physOptConf;
     }
 
@@ -129,4 +130,12 @@
                     CompilerProperties.COMPILER_SORT_SAMPLES_KEY, 1, "samples");
         }
     }
+
+    private static boolean isIndexOnly(CompilerProperties compilerProperties, Map<String, Object> querySpecificConfig) {
+        String valueInQuery = (String) querySpecificConfig.get(CompilerProperties.COMPILER_INDEXONLY_KEY);
+        if (valueInQuery != null) {
+            return OptionTypes.BOOLEAN.parse(valueInQuery);
+        }
+        return compilerProperties.isIndexOnly();
+    }
 }
diff --git a/asterixdb/asterix-doc/src/main/markdown/sqlpp/appendix_2_index_only.md b/asterixdb/asterix-doc/src/main/markdown/sqlpp/appendix_2_index_only.md
index 7a71259..93082f7 100644
--- a/asterixdb/asterix-doc/src/main/markdown/sqlpp/appendix_2_index_only.md
+++ b/asterixdb/asterix-doc/src/main/markdown/sqlpp/appendix_2_index_only.md
@@ -27,11 +27,11 @@
 a non-index-only plan that needs to search the primary index.
 However, this index-only plan can be turned off per query by setting the following parameter.
 
-*  **noindexonly**: if this is set to true, the index-only-plan will not be applied; the default value is false.
+*  **compiler.indexonly**: if this is set to false, the index-only-plan will not be applied; the default value is true.
 
 ##### Example
 
-    SET noindexonly 'true';
+    set `compiler.indexonly` "false";
 
     SELECT m.message AS message
     FROM GleambookMessages m where m.message = " love product-b its shortcut-menu is awesome:)";
diff --git a/hyracks-fullstack/algebricks/algebricks-core/src/main/java/org/apache/hyracks/algebricks/core/config/AlgebricksConfig.java b/hyracks-fullstack/algebricks/algebricks-core/src/main/java/org/apache/hyracks/algebricks/core/config/AlgebricksConfig.java
index 15bb54b..0ab21b4 100644
--- a/hyracks-fullstack/algebricks/algebricks-core/src/main/java/org/apache/hyracks/algebricks/core/config/AlgebricksConfig.java
+++ b/hyracks-fullstack/algebricks/algebricks-core/src/main/java/org/apache/hyracks/algebricks/core/config/AlgebricksConfig.java
@@ -27,4 +27,5 @@
     public static final Logger ALGEBRICKS_LOGGER = LogManager.getLogger(ALGEBRICKS_LOGGER_NAME);
     public static final int SORT_SAMPLES = 100;
     public static final boolean SORT_PARALLEL = true;
+    public static final boolean INDEX_ONLY_DEFAULT = true;
 }
diff --git a/hyracks-fullstack/algebricks/algebricks-core/src/main/java/org/apache/hyracks/algebricks/core/rewriter/base/PhysicalOptimizationConfig.java b/hyracks-fullstack/algebricks/algebricks-core/src/main/java/org/apache/hyracks/algebricks/core/rewriter/base/PhysicalOptimizationConfig.java
index 598497c..22eeb23 100644
--- a/hyracks-fullstack/algebricks/algebricks-core/src/main/java/org/apache/hyracks/algebricks/core/rewriter/base/PhysicalOptimizationConfig.java
+++ b/hyracks-fullstack/algebricks/algebricks-core/src/main/java/org/apache/hyracks/algebricks/core/rewriter/base/PhysicalOptimizationConfig.java
@@ -39,6 +39,7 @@
     private static final String DEFAULT_IN_MEM_HASH_JOIN_TABLE_SIZE = "DEFAULT_IN_MEM_HASH_JOIN_TABLE_SIZE";
     private static final String SORT_PARALLEL = "SORT_PARALLEL";
     private static final String SORT_SAMPLES = "SORT_SAMPLES";
+    private static final String INDEX_ONLY = "INDEX_ONLY";
 
     private Properties properties = new Properties();
 
@@ -172,6 +173,14 @@
         setInt(SORT_SAMPLES, sortSamples);
     }
 
+    public void setIndexOnly(boolean indexOnly) {
+        setBoolean(INDEX_ONLY, indexOnly);
+    }
+
+    public boolean isIndexOnly() {
+        return getBoolean(INDEX_ONLY, AlgebricksConfig.INDEX_ONLY_DEFAULT);
+    }
+
     private void setInt(String property, int value) {
         properties.setProperty(property, Integer.toString(value));
     }