This is an automated email from the ASF dual-hosted git repository.

preetham02 pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/asterixdb.git


The following commit(s) were added to refs/heads/master by this push:
     new fe605ba8f9 [ASTERIXDB-3666][COMP] : Fix index scan to apply range 
predicates on composite indexes
fe605ba8f9 is described below

commit fe605ba8f9d9e2b8b583f6f44cddb59fb74ddf02
Author: preetham0202 <[email protected]>
AuthorDate: Fri Oct 17 18:06:37 2025 +0530

    [ASTERIXDB-3666][COMP] : Fix index scan to apply range predicates on 
composite indexes
    
    - user model changes: no
    - storage format changes: no
    - interface changes: no
    
    Ext-ref: MB-68515
    
    Change-Id: Ia29c5f931c297a5c2517c2a35d16651411d0c5a4
    Reviewed-on: https://asterix-gerrit.ics.uci.edu/c/asterixdb/+/20495
    Reviewed-by: Ali Alsuliman <[email protected]>
    Reviewed-by: Preetham Poluparthi <[email protected]>
    Tested-by: Preetham Poluparthi <[email protected]>
---
 .../optimizer/rules/am/BTreeAccessMethod.java      | 35 ++++++++++++------
 .../results/btree-index/btree-secondary-44.plan    | 12 +++---
 .../results/btree-index/btree-secondary-45.plan    | 12 +++---
 .../results/btree-index/btree-secondary-62.plan    | 12 +++---
 .../results/btree-index/btree-secondary-63.plan    | 12 +++---
 .../btree-composite-key-non-enforced-04.plan       | 12 +++---
 .../btree-index-range.01.ddl.sqlpp                 | 30 +++++++++++++++
 .../btree-index-range.02.update.sqlpp              | 43 ++++++++++++++++++++++
 .../btree-index-range.03.ddl.sqlpp                 | 28 ++++++++++++++
 .../btree-index-range.04.query.sqlpp               | 28 ++++++++++++++
 .../btree-index-range.05.query.sqlpp               | 28 ++++++++++++++
 .../btree-index-range.06.query.sqlpp               | 29 +++++++++++++++
 .../btree-index-range.07.query.sqlpp               | 30 +++++++++++++++
 .../btree-index-range.08.query.sqlpp               | 30 +++++++++++++++
 .../btree-index-range.09.ddl.sqlpp                 | 31 ++++++++++++++++
 .../btree-index-range.10.query.sqlpp               | 29 +++++++++++++++
 .../btree-index-range.11.query.sqlpp               | 28 ++++++++++++++
 .../simple-index-only-compund-keys.6.plan          | 20 +++++-----
 .../btree-index-range/btree-index-range.04.adm     | 36 ++++++++++++++++++
 .../btree-index-range/btree-index-range.05.adm     |  1 +
 .../btree-index-range/btree-index-range.06.adm     | 34 +++++++++++++++++
 .../btree-index-range/btree-index-range.07.adm     |  1 +
 .../btree-index-range/btree-index-range.08.adm     | 36 ++++++++++++++++++
 .../btree-index-range/btree-index-range.10.adm     | 36 ++++++++++++++++++
 .../btree-index-range/btree-index-range.11.adm     |  1 +
 .../btree-index-range/btree-index-range.04.adm     | 24 ++++++++++++
 .../btree-index-range/btree-index-range.06.adm     | 34 +++++++++++++++++
 .../btree-index-range/btree-index-range.08.adm     | 24 ++++++++++++
 .../btree-index-range/btree-index-range.10.adm     | 36 ++++++++++++++++++
 .../simple-index-only-compund-keys.6.plan          | 20 +++++-----
 .../btree-index-range/btree-index-range.04.adm     | 36 ++++++++++++++++++
 .../btree-index-range/btree-index-range.06.adm     | 34 +++++++++++++++++
 .../btree-index-range/btree-index-range.08.adm     | 36 ++++++++++++++++++
 .../btree-index-range/btree-index-range.10.adm     | 36 ++++++++++++++++++
 .../src/test/resources/runtimets/sqlpp_queries.xml |  5 +++
 35 files changed, 818 insertions(+), 61 deletions(-)

diff --git 
a/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/am/BTreeAccessMethod.java
 
b/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/am/BTreeAccessMethod.java
index 18642b27f1..14cb45378d 100644
--- 
a/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/am/BTreeAccessMethod.java
+++ 
b/asterixdb/asterix-algebra/src/main/java/org/apache/asterix/optimizer/rules/am/BTreeAccessMethod.java
@@ -591,12 +591,24 @@ public class BTreeAccessMethod implements IAccessMethod {
             }
         }
 
-        // determine cases when prefix search could be applied
-        for (int i = 1; i < lowKeyExprs.length; i++) {
-            if (lowKeyLimits[0] == null && lowKeyLimits[i] != null || 
lowKeyLimits[0] != null && lowKeyLimits[i] == null
-                    || highKeyLimits[0] == null && highKeyLimits[i] != null
-                    || highKeyLimits[0] != null && highKeyLimits[i] == null) {
-                numSecondaryKeys = i;
+        int numLowKeys = 0;
+        for (LimitType limitType : lowKeyLimits) {
+            if (limitType != null) {
+                numLowKeys++;
+            } else
+                break;
+        }
+
+        int numHighKeys = 0;
+        for (LimitType limitType : highKeyLimits) {
+            if (limitType != null) {
+                numHighKeys++;
+            } else
+                break;
+        }
+
+        for (int i = 0; i < lowKeyExprs.length; i++) {
+            if (lowKeyLimits[i] != null && i >= numLowKeys || highKeyLimits[i] 
!= null && i >= numHighKeys) {
                 primaryIndexPostProccessingIsNeeded = true;
                 break;
             }
@@ -621,11 +633,12 @@ public class BTreeAccessMethod implements IAccessMethod {
         // List of variables and expressions for the assign.
         ArrayList<LogicalVariable> assignKeyVarList = new ArrayList<>();
         ArrayList<Mutable<ILogicalExpression>> assignKeyExprList = new 
ArrayList<>();
-        int numLowKeys = createKeyVarsAndExprs(numSecondaryKeys, lowKeyLimits, 
lowKeyExprs, assignKeyVarList,
-                assignKeyExprList, keyVarList, context, 
lowKeyConstAtRuntimeExpressions, lowKeyConstAtRuntimeExprVars);
-        int numHighKeys = createKeyVarsAndExprs(numSecondaryKeys, 
highKeyLimits, highKeyExprs, assignKeyVarList,
-                assignKeyExprList, keyVarList, context, 
highKeyConstantAtRuntimeExpressions,
-                highKeyConstAtRuntimeExprVars);
+
+        numLowKeys = createKeyVarsAndExprs(numLowKeys, lowKeyLimits, 
lowKeyExprs, assignKeyVarList, assignKeyExprList,
+                keyVarList, context, lowKeyConstAtRuntimeExpressions, 
lowKeyConstAtRuntimeExprVars);
+        numHighKeys =
+                createKeyVarsAndExprs(numHighKeys, highKeyLimits, 
highKeyExprs, assignKeyVarList, assignKeyExprList,
+                        keyVarList, context, 
highKeyConstantAtRuntimeExpressions, highKeyConstAtRuntimeExprVars);
 
         BTreeJobGenParams jobGenParams =
                 new BTreeJobGenParams(chosenIndex.getIndexName(), 
IndexType.BTREE, dataset.getDatabaseName(),
diff --git 
a/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index/btree-secondary-44.plan
 
b/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index/btree-secondary-44.plan
index 1da8796053..725150f250 100644
--- 
a/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index/btree-secondary-44.plan
+++ 
b/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index/btree-secondary-44.plan
@@ -8,23 +8,23 @@ distribute result [$$emp]
       -- STREAM_PROJECT  |PARTITIONED|
         exchange
         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-          unnest-map [$$18, $$emp] <- index-search("testdst", 0, "Default", 
"test", "testdst", false, false, 1, $$24, 1, $$24, true, true, true)
+          unnest-map [$$18, $$emp] <- index-search("testdst", 0, "Default", 
"test", "testdst", false, false, 1, $$25, 1, $$25, true, true, true)
           -- BTREE_SEARCH  |PARTITIONED|
             exchange
             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-              order (ASC, $$24)
-              -- STABLE_SORT [$$24(ASC)]  |PARTITIONED|
+              order (ASC, $$25)
+              -- STABLE_SORT [$$25(ASC)]  |PARTITIONED|
                 exchange
                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                  project ([$$24])
+                  project ([$$25])
                   -- STREAM_PROJECT  |PARTITIONED|
                     exchange
                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                      unnest-map [$$22, $$23, $$24] <- index-search("sec_Idx", 
0, "Default", "test", "testdst", false, false, 1, $$21, 0, true, true, true)
+                      unnest-map [$$23, $$24, $$25] <- index-search("sec_Idx", 
0, "Default", "test", "testdst", false, false, 2, $$21, $$22, 0, true, true, 
true)
                       -- BTREE_SEARCH  |PARTITIONED|
                         exchange
                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                          assign [$$21] <- ["Allan"]
+                          assign [$$21, $$22] <- ["Allan", "Xu"]
                           -- ASSIGN  |PARTITIONED|
                             empty-tuple-source
                             -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git 
a/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index/btree-secondary-45.plan
 
b/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index/btree-secondary-45.plan
index 783199dd58..394eaeb1d0 100644
--- 
a/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index/btree-secondary-45.plan
+++ 
b/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index/btree-secondary-45.plan
@@ -8,23 +8,23 @@ distribute result [$$emp]
       -- STREAM_PROJECT  |PARTITIONED|
         exchange
         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-          unnest-map [$$18, $$emp] <- index-search("testdst", 0, "Default", 
"test", "testdst", false, false, 1, $$25, 1, $$25, true, true, true)
+          unnest-map [$$18, $$emp] <- index-search("testdst", 0, "Default", 
"test", "testdst", false, false, 1, $$26, 1, $$26, true, true, true)
           -- BTREE_SEARCH  |PARTITIONED|
             exchange
             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-              order (ASC, $$25)
-              -- STABLE_SORT [$$25(ASC)]  |PARTITIONED|
+              order (ASC, $$26)
+              -- STABLE_SORT [$$26(ASC)]  |PARTITIONED|
                 exchange
                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                  project ([$$25])
+                  project ([$$26])
                   -- STREAM_PROJECT  |PARTITIONED|
                     exchange
                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                      unnest-map [$$23, $$24, $$25] <- index-search("sec_Idx", 
0, "Default", "test", "testdst", false, false, 1, $$21, 1, $$22, true, true, 
true)
+                      unnest-map [$$24, $$25, $$26] <- index-search("sec_Idx", 
0, "Default", "test", "testdst", false, false, 1, $$21, 2, $$22, $$23, false, 
false, true)
                       -- BTREE_SEARCH  |PARTITIONED|
                         exchange
                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                          assign [$$21, $$22] <- ["Julio", "Julio"]
+                          assign [$$21, $$22, $$23] <- ["Julio", "Julio", "Xu"]
                           -- ASSIGN  |PARTITIONED|
                             empty-tuple-source
                             -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git 
a/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index/btree-secondary-62.plan
 
b/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index/btree-secondary-62.plan
index c000e5511c..9bf798c1b3 100644
--- 
a/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index/btree-secondary-62.plan
+++ 
b/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index/btree-secondary-62.plan
@@ -8,23 +8,23 @@ distribute result [$$emp]
       -- STREAM_PROJECT  |PARTITIONED|
         exchange
         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-          unnest-map [$$18, $$emp] <- index-search("testdst", 0, "Default", 
"test", "testdst", false, false, 1, $$25, 1, $$25, true, true, true)
+          unnest-map [$$18, $$emp] <- index-search("testdst", 0, "Default", 
"test", "testdst", false, false, 1, $$26, 1, $$26, true, true, true)
           -- BTREE_SEARCH  |PARTITIONED|
             exchange
             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-              order (ASC, $$25)
-              -- STABLE_SORT [$$25(ASC)]  |PARTITIONED|
+              order (ASC, $$26)
+              -- STABLE_SORT [$$26(ASC)]  |PARTITIONED|
                 exchange
                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                  project ([$$25])
+                  project ([$$26])
                   -- STREAM_PROJECT  |PARTITIONED|
                     exchange
                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                      unnest-map [$$23, $$24, $$25] <- index-search("sec_Idx", 
0, "Default", "test", "testdst", false, false, 1, $$21, 1, $$22, true, true, 
true)
+                      unnest-map [$$24, $$25, $$26] <- index-search("sec_Idx", 
0, "Default", "test", "testdst", false, false, 2, $$21, $$22, 1, $$23, false, 
false, true)
                       -- BTREE_SEARCH  |PARTITIONED|
                         exchange
                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                          assign [$$21, $$22] <- ["Julio", "Julio"]
+                          assign [$$21, $$22, $$23] <- ["Julio", "Xu", "Julio"]
                           -- ASSIGN  |PARTITIONED|
                             empty-tuple-source
                             -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git 
a/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index/btree-secondary-63.plan
 
b/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index/btree-secondary-63.plan
index d632c0b540..7990d51f05 100644
--- 
a/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index/btree-secondary-63.plan
+++ 
b/asterixdb/asterix-app/src/test/resources/optimizerts/results/btree-index/btree-secondary-63.plan
@@ -8,23 +8,23 @@ distribute result [$$emp]
       -- STREAM_PROJECT  |PARTITIONED|
         exchange
         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-          unnest-map [$$18, $$emp] <- index-search("testdst", 0, "Default", 
"test", "testdst", false, false, 1, $$24, 1, $$24, true, true, true)
+          unnest-map [$$18, $$emp] <- index-search("testdst", 0, "Default", 
"test", "testdst", false, false, 1, $$25, 1, $$25, true, true, true)
           -- BTREE_SEARCH  |PARTITIONED|
             exchange
             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-              order (ASC, $$24)
-              -- STABLE_SORT [$$24(ASC)]  |PARTITIONED|
+              order (ASC, $$25)
+              -- STABLE_SORT [$$25(ASC)]  |PARTITIONED|
                 exchange
                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                  project ([$$24])
+                  project ([$$25])
                   -- STREAM_PROJECT  |PARTITIONED|
                     exchange
                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                      unnest-map [$$22, $$23, $$24] <- index-search("sec_Idx", 
0, "Default", "test", "testdst", false, false, 0, 1, $$21, true, true, true)
+                      unnest-map [$$23, $$24, $$25] <- index-search("sec_Idx", 
0, "Default", "test", "testdst", false, false, 0, 2, $$21, $$22, true, true, 
true)
                       -- BTREE_SEARCH  |PARTITIONED|
                         exchange
                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                          assign [$$21] <- ["Julio"]
+                          assign [$$21, $$22] <- ["Julio", "Xu"]
                           -- ASSIGN  |PARTITIONED|
                             empty-tuple-source
                             -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git 
a/asterixdb/asterix-app/src/test/resources/optimizerts/results/open-index-non-enforced/btree-composite-key-non-enforced/btree-composite-key-non-enforced-04.plan
 
b/asterixdb/asterix-app/src/test/resources/optimizerts/results/open-index-non-enforced/btree-composite-key-non-enforced/btree-composite-key-non-enforced-04.plan
index 186a8187d3..80e70de7c2 100644
--- 
a/asterixdb/asterix-app/src/test/resources/optimizerts/results/open-index-non-enforced/btree-composite-key-non-enforced/btree-composite-key-non-enforced-04.plan
+++ 
b/asterixdb/asterix-app/src/test/resources/optimizerts/results/open-index-non-enforced/btree-composite-key-non-enforced/btree-composite-key-non-enforced-04.plan
@@ -10,23 +10,23 @@ distribute result [$$21]
         -- STREAM_PROJECT  |PARTITIONED|
           exchange
           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-            unnest-map [$$22, $$t] <- index-search("TestOpen", 0, "Default", 
"test", "TestOpen", false, false, 1, $$31, 1, $$31, true, true, true)
+            unnest-map [$$22, $$t] <- index-search("TestOpen", 0, "Default", 
"test", "TestOpen", false, false, 1, $$33, 1, $$33, true, true, true)
             -- BTREE_SEARCH  |PARTITIONED|
               exchange
               -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                order (ASC, $$31)
-                -- STABLE_SORT [$$31(ASC)]  |PARTITIONED|
+                order (ASC, $$33)
+                -- STABLE_SORT [$$33(ASC)]  |PARTITIONED|
                   exchange
                   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                    project ([$$31])
+                    project ([$$33])
                     -- STREAM_PROJECT  |PARTITIONED|
                       exchange
                       -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                        unnest-map [$$28, $$29, $$30, $$31] <- 
index-search("idx_xyz", 0, "Default", "test", "TestOpen", false, false, 1, 
$$26, 1, $$27, true, true, true)
+                        unnest-map [$$30, $$31, $$32, $$33] <- 
index-search("idx_xyz", 0, "Default", "test", "TestOpen", false, false, 3, 
$$26, $$27, $$28, 1, $$29, true, true, true)
                         -- BTREE_SEARCH  |PARTITIONED|
                           exchange
                           -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                            assign [$$26, $$27] <- ["x2", "x2"]
+                            assign [$$26, $$27, $$28, $$29] <- ["x2", 1, "z2", 
"x2"]
                             -- ASSIGN  |PARTITIONED|
                               empty-tuple-source
                               -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git 
a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/index-selection/btree-index-range/btree-index-range.01.ddl.sqlpp
 
b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/index-selection/btree-index-range/btree-index-range.01.ddl.sqlpp
new file mode 100644
index 0000000000..d53c5ffff7
--- /dev/null
+++ 
b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/index-selection/btree-index-range/btree-index-range.01.ddl.sqlpp
@@ -0,0 +1,30 @@
+/*
+ * 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.
+ */
+/*
+ * Description  : Tests Range scans cover the right boundaries, Index spans 
show expected low/high keys.
+ * Issue        : 3666
+ * Expected Res : Success
+ */
+
+drop  dataverse test if exists;
+create  dataverse test;
+
+use test;
+
+CREATE DATASET A PRIMARY KEY ( id : integer);
diff --git 
a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/index-selection/btree-index-range/btree-index-range.02.update.sqlpp
 
b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/index-selection/btree-index-range/btree-index-range.02.update.sqlpp
new file mode 100644
index 0000000000..e6ea1640be
--- /dev/null
+++ 
b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/index-selection/btree-index-range/btree-index-range.02.update.sqlpp
@@ -0,0 +1,43 @@
+/*
+ * 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.
+ */
+/*
+ * Description  : Tests Range scans cover the right boundaries, Index spans 
show expected low/high keys.
+ * Issue        : 3666
+ * Expected Res : Success
+ */
+
+use test;
+
+
+INSERT INTO A (
+    SELECT VALUE {
+        "id" : i,
+        "a": i % 2,
+        "b": i % 3,
+        "c": i % 5,
+        "d": i,
+        "e": i % 3,
+        "f": i % 5,
+        "g": i % 7,
+        "h": i % 11,
+        "i": i % 13,
+        "j": i % 17
+    }
+    FROM range(1, 12000) i
+);
diff --git 
a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/index-selection/btree-index-range/btree-index-range.03.ddl.sqlpp
 
b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/index-selection/btree-index-range/btree-index-range.03.ddl.sqlpp
new file mode 100644
index 0000000000..7ce48f6525
--- /dev/null
+++ 
b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/index-selection/btree-index-range/btree-index-range.03.ddl.sqlpp
@@ -0,0 +1,28 @@
+/*
+ * 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.
+ */
+/*
+ * Description  : Tests Range scans cover the right boundaries, Index spans 
show expected low/high keys.
+ * Issue        : 3666
+ * Expected Res : Success
+ */
+
+use test;
+
+CREATE INDEX idx_abcd ON A (a, b, c, d) ;
+
diff --git 
a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/index-selection/btree-index-range/btree-index-range.04.query.sqlpp
 
b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/index-selection/btree-index-range/btree-index-range.04.query.sqlpp
new file mode 100644
index 0000000000..f8fbb10df9
--- /dev/null
+++ 
b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/index-selection/btree-index-range/btree-index-range.04.query.sqlpp
@@ -0,0 +1,28 @@
+/*
+ * 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.
+ */
+/*
+ * Description  : Tests Range scans cover the right boundaries, Index spans 
show expected low/high keys.
+ * Issue        : 3666
+ * Expected Res : Success
+ */
+
+use test;
+
+EXPLAIN SELECT count(*) FROM A WHERE a=1 AND b>0 AND c>2;
+
diff --git 
a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/index-selection/btree-index-range/btree-index-range.05.query.sqlpp
 
b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/index-selection/btree-index-range/btree-index-range.05.query.sqlpp
new file mode 100644
index 0000000000..117b062423
--- /dev/null
+++ 
b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/index-selection/btree-index-range/btree-index-range.05.query.sqlpp
@@ -0,0 +1,28 @@
+/*
+ * 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.
+ */
+/*
+ * Description  : Tests Range scans cover the right boundaries, Index spans 
show expected low/high keys.
+ * Issue        : 3666
+ * Expected Res : Success
+ */
+
+use test;
+// 1/2 * 2/3 * 2/5 * 12000 = 1600
+SELECT count(*) FROM A WHERE a=1 AND b>0 AND c>2;
+
diff --git 
a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/index-selection/btree-index-range/btree-index-range.06.query.sqlpp
 
b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/index-selection/btree-index-range/btree-index-range.06.query.sqlpp
new file mode 100644
index 0000000000..fc3322f406
--- /dev/null
+++ 
b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/index-selection/btree-index-range/btree-index-range.06.query.sqlpp
@@ -0,0 +1,29 @@
+/*
+ * 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.
+ */
+/*
+ * Description  : Tests Range scans cover the right boundaries, Index spans 
show expected low/high keys.
+ * Issue        : 3666
+ * Expected Res : Success
+ */
+
+use test;
+
+EXPLAIN SELECT count(*) FROM A WHERE a=0 AND b BETWEEN 1 AND 3  AND c>2 AND 
d<=6000;
+
+
diff --git 
a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/index-selection/btree-index-range/btree-index-range.07.query.sqlpp
 
b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/index-selection/btree-index-range/btree-index-range.07.query.sqlpp
new file mode 100644
index 0000000000..c1251e4114
--- /dev/null
+++ 
b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/index-selection/btree-index-range/btree-index-range.07.query.sqlpp
@@ -0,0 +1,30 @@
+/*
+ * 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.
+ */
+/*
+ * Description  : Tests Range scans cover the right boundaries, Index spans 
show expected low/high keys.
+ * Issue        : 3666
+ * Expected Res : Success
+ */
+
+use test;
+
+// 1/2 * 2/3 * 2/5 * 1/2 * 12000 = 800
+SELECT count(*) FROM A WHERE a=0 AND b BETWEEN 1 AND 6  AND c>2 AND d<=6000;
+
+
diff --git 
a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/index-selection/btree-index-range/btree-index-range.08.query.sqlpp
 
b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/index-selection/btree-index-range/btree-index-range.08.query.sqlpp
new file mode 100644
index 0000000000..1882da2a2f
--- /dev/null
+++ 
b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/index-selection/btree-index-range/btree-index-range.08.query.sqlpp
@@ -0,0 +1,30 @@
+/*
+ * 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.
+ */
+/*
+ * Description  : Tests Range scans cover the right boundaries, Index spans 
show expected low/high keys.
+ * Issue        : 3666
+ * Expected Res : Success
+ */
+
+use test;
+
+EXPLAIN SELECT count(*) FROM A WHERE a=1 AND b<2 AND c<4;
+
+
+
diff --git 
a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/index-selection/btree-index-range/btree-index-range.09.ddl.sqlpp
 
b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/index-selection/btree-index-range/btree-index-range.09.ddl.sqlpp
new file mode 100644
index 0000000000..5c358af5ff
--- /dev/null
+++ 
b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/index-selection/btree-index-range/btree-index-range.09.ddl.sqlpp
@@ -0,0 +1,31 @@
+/*
+ * 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.
+ */
+/*
+ * Description  : Tests Range scans cover the right boundaries, Index spans 
show expected low/high keys.
+ * Issue        : 3666
+ * Expected Res : Success
+ */
+
+use test;
+
+DROP INDEX A.idx_abcd;
+
+CREATE INDEX idx_all ON A (a,b,c,d,e,f,g,h,i,j);
+
+
diff --git 
a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/index-selection/btree-index-range/btree-index-range.10.query.sqlpp
 
b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/index-selection/btree-index-range/btree-index-range.10.query.sqlpp
new file mode 100644
index 0000000000..7ad9491b48
--- /dev/null
+++ 
b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/index-selection/btree-index-range/btree-index-range.10.query.sqlpp
@@ -0,0 +1,29 @@
+/*
+ * 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.
+ */
+/*
+ * Description  : Tests Range scans cover the right boundaries, Index spans 
show expected low/high keys.
+ * Issue        : 3666
+ * Expected Res : Success
+ */
+
+use test;
+
+EXPLAIN
+SELECT * FROM A
+WHERE a=0 AND b>=-1 AND b<=4  AND c>1 AND c<3 AND d>2000 AND d<2500 AND e>=-1 
AND e<4 AND f=2 AND g<1 and h<1;
diff --git 
a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/index-selection/btree-index-range/btree-index-range.11.query.sqlpp
 
b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/index-selection/btree-index-range/btree-index-range.11.query.sqlpp
new file mode 100644
index 0000000000..564bda0cfd
--- /dev/null
+++ 
b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/index-selection/btree-index-range/btree-index-range.11.query.sqlpp
@@ -0,0 +1,28 @@
+/*
+ * 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.
+ */
+/*
+ * Description  : Tests Range scans cover the right boundaries, Index spans 
show expected low/high keys.
+ * Issue        : 3666
+ * Expected Res : Success
+ */
+
+use test;
+
+SELECT * FROM A
+WHERE a=0 AND b>=-1 AND b<=4  AND c>1 AND c<3 AND d>2000 AND d<2500 AND e>=-1 
AND e<4 AND f=2 AND g<1 and h<1;
diff --git 
a/asterixdb/asterix-app/src/test/resources/runtimets/results/index-only-testcases/simple-index-only-compund-keys/simple-index-only-compund-keys.6.plan
 
b/asterixdb/asterix-app/src/test/resources/runtimets/results/index-only-testcases/simple-index-only-compund-keys/simple-index-only-compund-keys.6.plan
index 2d8ec816c8..d78da947da 100644
--- 
a/asterixdb/asterix-app/src/test/resources/runtimets/results/index-only-testcases/simple-index-only-compund-keys/simple-index-only-compund-keys.6.plan
+++ 
b/asterixdb/asterix-app/src/test/resources/runtimets/results/index-only-testcases/simple-index-only-compund-keys/simple-index-only-compund-keys.6.plan
@@ -1,30 +1,30 @@
-distribute result [$$22] [cardinality: 0.0, doc-size: 0.0, op-cost: 0.0, 
total-cost: 0.0]
+distribute result [$$24] [cardinality: 0.0, doc-size: 0.0, op-cost: 0.0, 
total-cost: 0.0]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
   exchange [cardinality: 0.0, doc-size: 0.0, op-cost: 0.0, total-cost: 0.0]
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-    assign [$$22] <- [{"cid": $$23, "orderstatus": $$24, "orderpriority": 
$$26}] project: [$$22] [cardinality: 0.0, doc-size: 0.0, op-cost: 0.0, 
total-cost: 0.0]
+    assign [$$24] <- [{"cid": $$25, "orderstatus": $$26, "orderpriority": 
$$28}] project: [$$24] [cardinality: 0.0, doc-size: 0.0, op-cost: 0.0, 
total-cost: 0.0]
     -- ASSIGN  |PARTITIONED|
-      project ([$$23, $$24, $$26]) [cardinality: 0.0, doc-size: 0.0, op-cost: 
0.0, total-cost: 0.0]
+      project ([$$25, $$26, $$28]) [cardinality: 0.0, doc-size: 0.0, op-cost: 
0.0, total-cost: 0.0]
       -- STREAM_PROJECT  |PARTITIONED|
         exchange [cardinality: 0.0, doc-size: 0.0, op-cost: 0.0, total-cost: 
0.0]
         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-          distinct ([$$31]) [cardinality: 0.0, doc-size: 0.0, op-cost: 0.0, 
total-cost: 0.0]
+          distinct ([$$34]) [cardinality: 0.0, doc-size: 0.0, op-cost: 0.0, 
total-cost: 0.0]
           -- PRE_SORTED_DISTINCT_BY  |PARTITIONED|
             exchange [cardinality: 0.0, doc-size: 0.0, op-cost: 0.0, 
total-cost: 0.0]
             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-              order (ASC, $$31) [cardinality: 0.0, doc-size: 0.0, op-cost: 
0.0, total-cost: 0.0]
-              -- STABLE_SORT [$$31(ASC)]  |PARTITIONED|
+              order (ASC, $$34) [cardinality: 0.0, doc-size: 0.0, op-cost: 
0.0, total-cost: 0.0]
+              -- STABLE_SORT [$$34(ASC)]  |PARTITIONED|
                 exchange [cardinality: 0.0, doc-size: 0.0, op-cost: 0.0, 
total-cost: 0.0]
                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                  select (and(eq($$24, "ORDER_DELIVERED"), lt($$23, 800))) 
[cardinality: 0.0, doc-size: 0.0, op-cost: 0.0, total-cost: 0.0]
+                  select (and(eq($$26, "ORDER_DELIVERED"), lt($$25, 800))) 
[cardinality: 0.0, doc-size: 0.0, op-cost: 0.0, total-cost: 0.0]
                   -- STREAM_SELECT  |PARTITIONED|
                     exchange [cardinality: 0.0, doc-size: 0.0, op-cost: 0.0, 
total-cost: 0.0]
                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                      unnest-map [$$23, $$24, $$26, $$31] <- 
index-search("CustomerID_idx", 0, "Default", "test", "Orders", false, false, 0, 
1, $$27, true, true, true) [cardinality: 0.0, doc-size: 0.0, op-cost: 0.0, 
total-cost: 0.0]
+                      unnest-map [$$25, $$26, $$28, $$34] <- 
index-search("CustomerID_idx", 0, "Default", "test", "Orders", false, false, 0, 
2, $$29, $$30, true, true, true) [cardinality: 0.0, doc-size: 0.0, op-cost: 
0.0, total-cost: 0.0]
                       -- BTREE_SEARCH  |PARTITIONED|
                         exchange [cardinality: 0.0, doc-size: 0.0, op-cost: 
0.0, total-cost: 0.0]
                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                          assign [$$27] <- [800] [cardinality: 0.0, doc-size: 
0.0, op-cost: 0.0, total-cost: 0.0]
+                          assign [$$29, $$30] <- [800, "ORDER_DELIVERED"] 
[cardinality: 0.0, doc-size: 0.0, op-cost: 0.0, total-cost: 0.0]
                           -- ASSIGN  |PARTITIONED|
                             empty-tuple-source [cardinality: 0.0, doc-size: 
0.0, op-cost: 0.0, total-cost: 0.0]
-                            -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
\ No newline at end of file
+                            -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git 
a/asterixdb/asterix-app/src/test/resources/runtimets/results/index-selection/btree-index-range/btree-index-range.04.adm
 
b/asterixdb/asterix-app/src/test/resources/runtimets/results/index-selection/btree-index-range/btree-index-range.04.adm
new file mode 100644
index 0000000000..17bca478d1
--- /dev/null
+++ 
b/asterixdb/asterix-app/src/test/resources/runtimets/results/index-selection/btree-index-range/btree-index-range.04.adm
@@ -0,0 +1,36 @@
+distribute result [$$45] [cardinality: 0.0, doc-size: 0.0, op-cost: 0.0, 
total-cost: 0.0]
+-- DISTRIBUTE_RESULT  |UNPARTITIONED|
+  exchange [cardinality: 0.0, doc-size: 0.0, op-cost: 0.0, total-cost: 0.0]
+  -- ONE_TO_ONE_EXCHANGE  |UNPARTITIONED|
+    assign [$$45] <- [{"$1": $$47}] project: [$$45] [cardinality: 0.0, 
doc-size: 0.0, op-cost: 0.0, total-cost: 0.0]
+    -- ASSIGN  |UNPARTITIONED|
+      aggregate [$$47] <- [agg-sql-sum($$51)] [cardinality: 0.0, doc-size: 
0.0, op-cost: 0.0, total-cost: 0.0]
+      -- AGGREGATE  |UNPARTITIONED|
+        exchange [cardinality: 0.0, doc-size: 0.0, op-cost: 0.0, total-cost: 
0.0]
+        -- RANDOM_MERGE_EXCHANGE  |PARTITIONED|
+          aggregate [$$51] <- [agg-sql-count(1)] [cardinality: 0.0, doc-size: 
0.0, op-cost: 0.0, total-cost: 0.0]
+          -- AGGREGATE  |PARTITIONED|
+            exchange [cardinality: 0.0, doc-size: 0.0, op-cost: 0.0, 
total-cost: 0.0]
+            -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+              distinct ([$$60]) [cardinality: 0.0, doc-size: 0.0, op-cost: 
0.0, total-cost: 0.0]
+              -- PRE_SORTED_DISTINCT_BY  |PARTITIONED|
+                exchange [cardinality: 0.0, doc-size: 0.0, op-cost: 0.0, 
total-cost: 0.0]
+                -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                  order (ASC, $$60) [cardinality: 0.0, doc-size: 0.0, op-cost: 
0.0, total-cost: 0.0]
+                  -- STABLE_SORT [$$60(ASC)]  |PARTITIONED|
+                    exchange [cardinality: 0.0, doc-size: 0.0, op-cost: 0.0, 
total-cost: 0.0]
+                    -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                      select (and(eq($$50, 1), gt($$49, 0), gt($$48, 2))) 
project: [$$60] [cardinality: 0.0, doc-size: 0.0, op-cost: 0.0, total-cost: 0.0]
+                      -- STREAM_SELECT  |PARTITIONED|
+                        project ([$$50, $$49, $$48, $$60]) [cardinality: 0.0, 
doc-size: 0.0, op-cost: 0.0, total-cost: 0.0]
+                        -- STREAM_PROJECT  |PARTITIONED|
+                          exchange [cardinality: 0.0, doc-size: 0.0, op-cost: 
0.0, total-cost: 0.0]
+                          -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                            unnest-map [$$50, $$49, $$48, $$59, $$60] <- 
index-search("idx_abcd", 0, "Default", "test", "A", false, false, 3, $$52, 
$$53, $$54, 1, $$55, true, true, true) [cardinality: 0.0, doc-size: 0.0, 
op-cost: 0.0, total-cost: 0.0]
+                            -- BTREE_SEARCH  |PARTITIONED|
+                              exchange [cardinality: 0.0, doc-size: 0.0, 
op-cost: 0.0, total-cost: 0.0]
+                              -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                assign [$$52, $$53, $$54, $$55] <- [1, 0, 2, 
1] [cardinality: 0.0, doc-size: 0.0, op-cost: 0.0, total-cost: 0.0]
+                                -- ASSIGN  |PARTITIONED|
+                                  empty-tuple-source [cardinality: 0.0, 
doc-size: 0.0, op-cost: 0.0, total-cost: 0.0]
+                                  -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git 
a/asterixdb/asterix-app/src/test/resources/runtimets/results/index-selection/btree-index-range/btree-index-range.05.adm
 
b/asterixdb/asterix-app/src/test/resources/runtimets/results/index-selection/btree-index-range/btree-index-range.05.adm
new file mode 100644
index 0000000000..1e070f43f0
--- /dev/null
+++ 
b/asterixdb/asterix-app/src/test/resources/runtimets/results/index-selection/btree-index-range/btree-index-range.05.adm
@@ -0,0 +1 @@
+{ "$1": 1600 }
\ No newline at end of file
diff --git 
a/asterixdb/asterix-app/src/test/resources/runtimets/results/index-selection/btree-index-range/btree-index-range.06.adm
 
b/asterixdb/asterix-app/src/test/resources/runtimets/results/index-selection/btree-index-range/btree-index-range.06.adm
new file mode 100644
index 0000000000..362e49007c
--- /dev/null
+++ 
b/asterixdb/asterix-app/src/test/resources/runtimets/results/index-selection/btree-index-range/btree-index-range.06.adm
@@ -0,0 +1,34 @@
+distribute result [$$50] [cardinality: 0.0, doc-size: 0.0, op-cost: 0.0, 
total-cost: 0.0]
+-- DISTRIBUTE_RESULT  |UNPARTITIONED|
+  exchange [cardinality: 0.0, doc-size: 0.0, op-cost: 0.0, total-cost: 0.0]
+  -- ONE_TO_ONE_EXCHANGE  |UNPARTITIONED|
+    assign [$$50] <- [{"$1": $$53}] project: [$$50] [cardinality: 0.0, 
doc-size: 0.0, op-cost: 0.0, total-cost: 0.0]
+    -- ASSIGN  |UNPARTITIONED|
+      aggregate [$$53] <- [agg-sql-sum($$57)] [cardinality: 0.0, doc-size: 
0.0, op-cost: 0.0, total-cost: 0.0]
+      -- AGGREGATE  |UNPARTITIONED|
+        exchange [cardinality: 0.0, doc-size: 0.0, op-cost: 0.0, total-cost: 
0.0]
+        -- RANDOM_MERGE_EXCHANGE  |PARTITIONED|
+          aggregate [$$57] <- [agg-sql-count(1)] [cardinality: 0.0, doc-size: 
0.0, op-cost: 0.0, total-cost: 0.0]
+          -- AGGREGATE  |PARTITIONED|
+            exchange [cardinality: 0.0, doc-size: 0.0, op-cost: 0.0, 
total-cost: 0.0]
+            -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+              distinct ([$$67]) [cardinality: 0.0, doc-size: 0.0, op-cost: 
0.0, total-cost: 0.0]
+              -- PRE_SORTED_DISTINCT_BY  |PARTITIONED|
+                exchange [cardinality: 0.0, doc-size: 0.0, op-cost: 0.0, 
total-cost: 0.0]
+                -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                  order (ASC, $$67) [cardinality: 0.0, doc-size: 0.0, op-cost: 
0.0, total-cost: 0.0]
+                  -- STABLE_SORT [$$67(ASC)]  |PARTITIONED|
+                    exchange [cardinality: 0.0, doc-size: 0.0, op-cost: 0.0, 
total-cost: 0.0]
+                    -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                      select (and(gt($$56, 2), le($$55, 6000), eq($$54, 0), 
le($$51, 3), ge($$51, 1))) project: [$$67] [cardinality: 0.0, doc-size: 0.0, 
op-cost: 0.0, total-cost: 0.0]
+                      -- STREAM_SELECT  |PARTITIONED|
+                        exchange [cardinality: 0.0, doc-size: 0.0, op-cost: 
0.0, total-cost: 0.0]
+                        -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                          unnest-map [$$54, $$51, $$56, $$55, $$67] <- 
index-search("idx_abcd", 0, "Default", "test", "A", false, false, 3, $$58, 
$$59, $$60, 2, $$61, $$62, true, true, true) [cardinality: 0.0, doc-size: 0.0, 
op-cost: 0.0, total-cost: 0.0]
+                          -- BTREE_SEARCH  |PARTITIONED|
+                            exchange [cardinality: 0.0, doc-size: 0.0, 
op-cost: 0.0, total-cost: 0.0]
+                            -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                              assign [$$58, $$59, $$60, $$61, $$62] <- [0, 1, 
2, 0, 3] [cardinality: 0.0, doc-size: 0.0, op-cost: 0.0, total-cost: 0.0]
+                              -- ASSIGN  |PARTITIONED|
+                                empty-tuple-source [cardinality: 0.0, 
doc-size: 0.0, op-cost: 0.0, total-cost: 0.0]
+                                -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git 
a/asterixdb/asterix-app/src/test/resources/runtimets/results/index-selection/btree-index-range/btree-index-range.07.adm
 
b/asterixdb/asterix-app/src/test/resources/runtimets/results/index-selection/btree-index-range/btree-index-range.07.adm
new file mode 100644
index 0000000000..b14ab4c988
--- /dev/null
+++ 
b/asterixdb/asterix-app/src/test/resources/runtimets/results/index-selection/btree-index-range/btree-index-range.07.adm
@@ -0,0 +1 @@
+{ "$1": 800 }
\ No newline at end of file
diff --git 
a/asterixdb/asterix-app/src/test/resources/runtimets/results/index-selection/btree-index-range/btree-index-range.08.adm
 
b/asterixdb/asterix-app/src/test/resources/runtimets/results/index-selection/btree-index-range/btree-index-range.08.adm
new file mode 100644
index 0000000000..eb49f3b47d
--- /dev/null
+++ 
b/asterixdb/asterix-app/src/test/resources/runtimets/results/index-selection/btree-index-range/btree-index-range.08.adm
@@ -0,0 +1,36 @@
+distribute result [$$45] [cardinality: 0.0, doc-size: 0.0, op-cost: 0.0, 
total-cost: 0.0]
+-- DISTRIBUTE_RESULT  |UNPARTITIONED|
+  exchange [cardinality: 0.0, doc-size: 0.0, op-cost: 0.0, total-cost: 0.0]
+  -- ONE_TO_ONE_EXCHANGE  |UNPARTITIONED|
+    assign [$$45] <- [{"$1": $$47}] project: [$$45] [cardinality: 0.0, 
doc-size: 0.0, op-cost: 0.0, total-cost: 0.0]
+    -- ASSIGN  |UNPARTITIONED|
+      aggregate [$$47] <- [agg-sql-sum($$51)] [cardinality: 0.0, doc-size: 
0.0, op-cost: 0.0, total-cost: 0.0]
+      -- AGGREGATE  |UNPARTITIONED|
+        exchange [cardinality: 0.0, doc-size: 0.0, op-cost: 0.0, total-cost: 
0.0]
+        -- RANDOM_MERGE_EXCHANGE  |PARTITIONED|
+          aggregate [$$51] <- [agg-sql-count(1)] [cardinality: 0.0, doc-size: 
0.0, op-cost: 0.0, total-cost: 0.0]
+          -- AGGREGATE  |PARTITIONED|
+            exchange [cardinality: 0.0, doc-size: 0.0, op-cost: 0.0, 
total-cost: 0.0]
+            -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+              distinct ([$$60]) [cardinality: 0.0, doc-size: 0.0, op-cost: 
0.0, total-cost: 0.0]
+              -- PRE_SORTED_DISTINCT_BY  |PARTITIONED|
+                exchange [cardinality: 0.0, doc-size: 0.0, op-cost: 0.0, 
total-cost: 0.0]
+                -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                  order (ASC, $$60) [cardinality: 0.0, doc-size: 0.0, op-cost: 
0.0, total-cost: 0.0]
+                  -- STABLE_SORT [$$60(ASC)]  |PARTITIONED|
+                    exchange [cardinality: 0.0, doc-size: 0.0, op-cost: 0.0, 
total-cost: 0.0]
+                    -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                      select (and(eq($$50, 1), lt($$49, 2), lt($$48, 4))) 
project: [$$60] [cardinality: 0.0, doc-size: 0.0, op-cost: 0.0, total-cost: 0.0]
+                      -- STREAM_SELECT  |PARTITIONED|
+                        project ([$$50, $$49, $$48, $$60]) [cardinality: 0.0, 
doc-size: 0.0, op-cost: 0.0, total-cost: 0.0]
+                        -- STREAM_PROJECT  |PARTITIONED|
+                          exchange [cardinality: 0.0, doc-size: 0.0, op-cost: 
0.0, total-cost: 0.0]
+                          -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                            unnest-map [$$50, $$49, $$48, $$59, $$60] <- 
index-search("idx_abcd", 0, "Default", "test", "A", false, false, 1, $$52, 3, 
$$53, $$54, $$55, true, true, true) [cardinality: 0.0, doc-size: 0.0, op-cost: 
0.0, total-cost: 0.0]
+                            -- BTREE_SEARCH  |PARTITIONED|
+                              exchange [cardinality: 0.0, doc-size: 0.0, 
op-cost: 0.0, total-cost: 0.0]
+                              -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                assign [$$52, $$53, $$54, $$55] <- [1, 1, 2, 
4] [cardinality: 0.0, doc-size: 0.0, op-cost: 0.0, total-cost: 0.0]
+                                -- ASSIGN  |PARTITIONED|
+                                  empty-tuple-source [cardinality: 0.0, 
doc-size: 0.0, op-cost: 0.0, total-cost: 0.0]
+                                  -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git 
a/asterixdb/asterix-app/src/test/resources/runtimets/results/index-selection/btree-index-range/btree-index-range.10.adm
 
b/asterixdb/asterix-app/src/test/resources/runtimets/results/index-selection/btree-index-range/btree-index-range.10.adm
new file mode 100644
index 0000000000..83bb34665f
--- /dev/null
+++ 
b/asterixdb/asterix-app/src/test/resources/runtimets/results/index-selection/btree-index-range/btree-index-range.10.adm
@@ -0,0 +1,36 @@
+distribute result [$$43] [cardinality: 0.0, doc-size: 0.0, op-cost: 0.0, 
total-cost: 0.0]
+-- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange [cardinality: 0.0, doc-size: 0.0, op-cost: 0.0, total-cost: 0.0]
+  -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$43] <- [{"A": $$A}] project: [$$43] [cardinality: 0.0, doc-size: 
0.0, op-cost: 0.0, total-cost: 0.0]
+    -- ASSIGN  |PARTITIONED|
+      select (and(eq($$A.getField("f"), 2), lt($$A.getField("g"), 1), 
lt($$A.getField("h"), 1), eq($$A.getField("a"), 0), lt($$44, 4), ge($$44, -1), 
lt($$45, 2500), gt($$45, 2000), lt($$46, 3), gt($$46, 1), le($$47, 4), ge($$47, 
-1))) project: [$$A] [cardinality: 0.0, doc-size: 0.0, op-cost: 0.0, 
total-cost: 0.0]
+      -- STREAM_SELECT  |PARTITIONED|
+        assign [$$47, $$46, $$45, $$44] <- [$$A.getField("b"), 
$$A.getField("c"), $$A.getField("d"), $$A.getField("e")] [cardinality: 0.0, 
doc-size: 0.0, op-cost: 0.0, total-cost: 0.0]
+        -- ASSIGN  |PARTITIONED|
+          project ([$$A]) [cardinality: 0.0, doc-size: 0.0, op-cost: 0.0, 
total-cost: 0.0]
+          -- STREAM_PROJECT  |PARTITIONED|
+            exchange [cardinality: 0.0, doc-size: 0.0, op-cost: 0.0, 
total-cost: 0.0]
+            -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+              unnest-map [$$48, $$A] <- index-search("A", 0, "Default", 
"test", "A", false, false, 1, $$77, 1, $$77, true, true, true) [cardinality: 
0.0, doc-size: 0.0, op-cost: 0.0, total-cost: 0.0]
+              -- BTREE_SEARCH  |PARTITIONED|
+                exchange [cardinality: 0.0, doc-size: 0.0, op-cost: 0.0, 
total-cost: 0.0]
+                -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                  order (ASC, $$77) [cardinality: 0.0, doc-size: 0.0, op-cost: 
0.0, total-cost: 0.0]
+                  -- STABLE_SORT [$$77(ASC)]  |PARTITIONED|
+                    exchange [cardinality: 0.0, doc-size: 0.0, op-cost: 0.0, 
total-cost: 0.0]
+                    -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                      select (and(eq($$72, 2), lt($$73, 1), lt($$74, 1), 
eq($$67, 0), lt($$71, 4), ge($$71, -1), lt($$70, 2500), gt($$70, 2000), 
lt($$69, 3), gt($$69, 1), le($$68, 4), ge($$68, -1))) project: [$$77] 
[cardinality: 0.0, doc-size: 0.0, op-cost: 0.0, total-cost: 0.0]
+                      -- STREAM_SELECT  |PARTITIONED|
+                        project ([$$67, $$68, $$69, $$70, $$71, $$72, $$73, 
$$74, $$77]) [cardinality: 0.0, doc-size: 0.0, op-cost: 0.0, total-cost: 0.0]
+                        -- STREAM_PROJECT  |PARTITIONED|
+                          exchange [cardinality: 0.0, doc-size: 0.0, op-cost: 
0.0, total-cost: 0.0]
+                          -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                            unnest-map [$$67, $$68, $$69, $$70, $$71, $$72, 
$$73, $$74, $$75, $$76, $$77] <- index-search("idx_all", 0, "Default", "test", 
"A", false, false, 6, $$53, $$54, $$55, $$56, $$57, $$58, 8, $$59, $$60, $$61, 
$$62, $$63, $$64, $$65, $$66, true, true, true) [cardinality: 0.0, doc-size: 
0.0, op-cost: 0.0, total-cost: 0.0]
+                            -- BTREE_SEARCH  |PARTITIONED|
+                              exchange [cardinality: 0.0, doc-size: 0.0, 
op-cost: 0.0, total-cost: 0.0]
+                              -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                assign [$$53, $$54, $$55, $$56, $$57, $$58, 
$$59, $$60, $$61, $$62, $$63, $$64, $$65, $$66] <- [0, -1, 1, 2000, -1, 2, 0, 
4, 3, 2500, 4, 2, 1, 1] [cardinality: 0.0, doc-size: 0.0, op-cost: 0.0, 
total-cost: 0.0]
+                                -- ASSIGN  |PARTITIONED|
+                                  empty-tuple-source [cardinality: 0.0, 
doc-size: 0.0, op-cost: 0.0, total-cost: 0.0]
+                                  -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git 
a/asterixdb/asterix-app/src/test/resources/runtimets/results/index-selection/btree-index-range/btree-index-range.11.adm
 
b/asterixdb/asterix-app/src/test/resources/runtimets/results/index-selection/btree-index-range/btree-index-range.11.adm
new file mode 100644
index 0000000000..a61a9d4d74
--- /dev/null
+++ 
b/asterixdb/asterix-app/src/test/resources/runtimets/results/index-selection/btree-index-range/btree-index-range.11.adm
@@ -0,0 +1 @@
+{ "A": { "id": 2002, "a": 0, "b": 1, "c": 2, "d": 2002, "e": 1, "f": 2, "g": 
0, "h": 0, "i": 0, "j": 13 } }
\ No newline at end of file
diff --git 
a/asterixdb/asterix-app/src/test/resources/runtimets/results_cbo/index-selection/btree-index-range/btree-index-range.04.adm
 
b/asterixdb/asterix-app/src/test/resources/runtimets/results_cbo/index-selection/btree-index-range/btree-index-range.04.adm
new file mode 100644
index 0000000000..610385abe6
--- /dev/null
+++ 
b/asterixdb/asterix-app/src/test/resources/runtimets/results_cbo/index-selection/btree-index-range/btree-index-range.04.adm
@@ -0,0 +1,24 @@
+distribute result [$$45] [cardinality: 1411.1, doc-size: 0.0, op-cost: 0.0, 
total-cost: 12000.0]
+-- DISTRIBUTE_RESULT  |UNPARTITIONED|
+  exchange [cardinality: 1411.1, doc-size: 0.0, op-cost: 0.0, total-cost: 
12000.0]
+  -- ONE_TO_ONE_EXCHANGE  |UNPARTITIONED|
+    assign [$$45] <- [{"$1": $$47}] project: [$$45] [cardinality: 1411.1, 
doc-size: 0.0, op-cost: 0.0, total-cost: 12000.0]
+    -- ASSIGN  |UNPARTITIONED|
+      aggregate [$$47] <- [agg-sql-sum($$51)] [cardinality: 1411.1, doc-size: 
0.0, op-cost: 0.0, total-cost: 12000.0]
+      -- AGGREGATE  |UNPARTITIONED|
+        exchange [cardinality: 1411.1, doc-size: 0.0, op-cost: 0.0, 
total-cost: 12000.0]
+        -- RANDOM_MERGE_EXCHANGE  |PARTITIONED|
+          aggregate [$$51] <- [agg-sql-count(1)] [cardinality: 1411.1, 
doc-size: 0.0, op-cost: 0.0, total-cost: 12000.0]
+          -- AGGREGATE  |PARTITIONED|
+            select (and(eq($$A.getField("a"), 1), gt($$A.getField("b"), 0), 
gt($$A.getField("c"), 2))) [cardinality: 1411.1, doc-size: 0.0, op-cost: 0.0, 
total-cost: 12000.0]
+            -- STREAM_SELECT  |PARTITIONED|
+              project ([$$A]) [cardinality: 12000.0, doc-size: 0.0, op-cost: 
0.0, total-cost: 12000.0]
+              -- STREAM_PROJECT  |PARTITIONED|
+                exchange [cardinality: 12000.0, doc-size: 0.0, op-cost: 0.0, 
total-cost: 12000.0]
+                -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                  data-scan []<-[$$46, $$A] <- test.A [cardinality: 12000.0, 
doc-size: 0.0, op-cost: 0.0, total-cost: 12000.0]
+                  -- DATASOURCE_SCAN  |PARTITIONED|
+                    exchange [cardinality: 0.0, doc-size: 0.0, op-cost: 0.0, 
total-cost: 0.0]
+                    -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                      empty-tuple-source [cardinality: 0.0, doc-size: 0.0, 
op-cost: 0.0, total-cost: 0.0]
+                      -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git 
a/asterixdb/asterix-app/src/test/resources/runtimets/results_cbo/index-selection/btree-index-range/btree-index-range.06.adm
 
b/asterixdb/asterix-app/src/test/resources/runtimets/results_cbo/index-selection/btree-index-range/btree-index-range.06.adm
new file mode 100644
index 0000000000..0ce1a38061
--- /dev/null
+++ 
b/asterixdb/asterix-app/src/test/resources/runtimets/results_cbo/index-selection/btree-index-range/btree-index-range.06.adm
@@ -0,0 +1,34 @@
+distribute result [$$50] [cardinality: 778.93, doc-size: 0.0, op-cost: 0.0, 
total-cost: 162608.96]
+-- DISTRIBUTE_RESULT  |UNPARTITIONED|
+  exchange [cardinality: 778.93, doc-size: 0.0, op-cost: 0.0, total-cost: 
162608.96]
+  -- ONE_TO_ONE_EXCHANGE  |UNPARTITIONED|
+    assign [$$50] <- [{"$1": $$53}] project: [$$50] [cardinality: 778.93, 
doc-size: 0.0, op-cost: 0.0, total-cost: 162608.96]
+    -- ASSIGN  |UNPARTITIONED|
+      aggregate [$$53] <- [agg-sql-sum($$57)] [cardinality: 778.93, doc-size: 
0.0, op-cost: 0.0, total-cost: 162608.96]
+      -- AGGREGATE  |UNPARTITIONED|
+        exchange [cardinality: 778.93, doc-size: 0.0, op-cost: 0.0, 
total-cost: 162608.96]
+        -- RANDOM_MERGE_EXCHANGE  |PARTITIONED|
+          aggregate [$$57] <- [agg-sql-count(1)] [cardinality: 778.93, 
doc-size: 0.0, op-cost: 0.0, total-cost: 162608.96]
+          -- AGGREGATE  |PARTITIONED|
+            exchange [cardinality: 778.93, doc-size: 0.0, op-cost: 0.0, 
total-cost: 162608.96]
+            -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+              distinct ([$$67]) [cardinality: 778.93, doc-size: 0.0, op-cost: 
0.0, total-cost: 162608.96]
+              -- PRE_SORTED_DISTINCT_BY  |PARTITIONED|
+                exchange [cardinality: 0.0, doc-size: 0.0, op-cost: 0.0, 
total-cost: 0.0]
+                -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                  order (ASC, $$67) [cardinality: 0.0, doc-size: 0.0, op-cost: 
0.0, total-cost: 0.0]
+                  -- STABLE_SORT [$$67(ASC)]  |PARTITIONED|
+                    exchange [cardinality: 0.0, doc-size: 0.0, op-cost: 0.0, 
total-cost: 0.0]
+                    -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                      select (and(gt($$56, 2), le($$55, 6000), eq($$54, 0), 
le($$51, 3), ge($$51, 1))) project: [$$67] [cardinality: 0.0, doc-size: 0.0, 
op-cost: 0.0, total-cost: 0.0]
+                      -- STREAM_SELECT  |PARTITIONED|
+                        exchange [cardinality: 0.0, doc-size: 0.0, op-cost: 
0.0, total-cost: 0.0]
+                        -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                          unnest-map [$$54, $$51, $$56, $$55, $$67] <- 
index-search("idx_abcd", 0, "Default", "test", "A", false, false, 3, $$58, 
$$59, $$60, 2, $$61, $$62, true, true, true) [cardinality: 0.0, doc-size: 0.0, 
op-cost: 0.0, total-cost: 0.0]
+                          -- BTREE_SEARCH  |PARTITIONED|
+                            exchange [cardinality: 0.0, doc-size: 0.0, 
op-cost: 0.0, total-cost: 0.0]
+                            -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                              assign [$$58, $$59, $$60, $$61, $$62] <- [0, 1, 
2, 0, 3] [cardinality: 0.0, doc-size: 0.0, op-cost: 0.0, total-cost: 0.0]
+                              -- ASSIGN  |PARTITIONED|
+                                empty-tuple-source [cardinality: 0.0, 
doc-size: 0.0, op-cost: 0.0, total-cost: 0.0]
+                                -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git 
a/asterixdb/asterix-app/src/test/resources/runtimets/results_cbo/index-selection/btree-index-range/btree-index-range.08.adm
 
b/asterixdb/asterix-app/src/test/resources/runtimets/results_cbo/index-selection/btree-index-range/btree-index-range.08.adm
new file mode 100644
index 0000000000..f1b2d8f58a
--- /dev/null
+++ 
b/asterixdb/asterix-app/src/test/resources/runtimets/results_cbo/index-selection/btree-index-range/btree-index-range.08.adm
@@ -0,0 +1,24 @@
+distribute result [$$45] [cardinality: 3206.02, doc-size: 0.0, op-cost: 0.0, 
total-cost: 12000.0]
+-- DISTRIBUTE_RESULT  |UNPARTITIONED|
+  exchange [cardinality: 3206.02, doc-size: 0.0, op-cost: 0.0, total-cost: 
12000.0]
+  -- ONE_TO_ONE_EXCHANGE  |UNPARTITIONED|
+    assign [$$45] <- [{"$1": $$47}] project: [$$45] [cardinality: 3206.02, 
doc-size: 0.0, op-cost: 0.0, total-cost: 12000.0]
+    -- ASSIGN  |UNPARTITIONED|
+      aggregate [$$47] <- [agg-sql-sum($$51)] [cardinality: 3206.02, doc-size: 
0.0, op-cost: 0.0, total-cost: 12000.0]
+      -- AGGREGATE  |UNPARTITIONED|
+        exchange [cardinality: 3206.02, doc-size: 0.0, op-cost: 0.0, 
total-cost: 12000.0]
+        -- RANDOM_MERGE_EXCHANGE  |PARTITIONED|
+          aggregate [$$51] <- [agg-sql-count(1)] [cardinality: 3206.02, 
doc-size: 0.0, op-cost: 0.0, total-cost: 12000.0]
+          -- AGGREGATE  |PARTITIONED|
+            select (and(eq($$A.getField("a"), 1), lt($$A.getField("b"), 2), 
lt($$A.getField("c"), 4))) [cardinality: 3206.02, doc-size: 0.0, op-cost: 0.0, 
total-cost: 12000.0]
+            -- STREAM_SELECT  |PARTITIONED|
+              project ([$$A]) [cardinality: 12000.0, doc-size: 0.0, op-cost: 
0.0, total-cost: 12000.0]
+              -- STREAM_PROJECT  |PARTITIONED|
+                exchange [cardinality: 12000.0, doc-size: 0.0, op-cost: 0.0, 
total-cost: 12000.0]
+                -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                  data-scan []<-[$$46, $$A] <- test.A [cardinality: 12000.0, 
doc-size: 0.0, op-cost: 0.0, total-cost: 12000.0]
+                  -- DATASOURCE_SCAN  |PARTITIONED|
+                    exchange [cardinality: 0.0, doc-size: 0.0, op-cost: 0.0, 
total-cost: 0.0]
+                    -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                      empty-tuple-source [cardinality: 0.0, doc-size: 0.0, 
op-cost: 0.0, total-cost: 0.0]
+                      -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git 
a/asterixdb/asterix-app/src/test/resources/runtimets/results_cbo/index-selection/btree-index-range/btree-index-range.10.adm
 
b/asterixdb/asterix-app/src/test/resources/runtimets/results_cbo/index-selection/btree-index-range/btree-index-range.10.adm
new file mode 100644
index 0000000000..35ce020226
--- /dev/null
+++ 
b/asterixdb/asterix-app/src/test/resources/runtimets/results_cbo/index-selection/btree-index-range/btree-index-range.10.adm
@@ -0,0 +1,36 @@
+distribute result [$$43] [cardinality: 2.1, doc-size: 216.0, op-cost: 0.0, 
total-cost: 0.0]
+-- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange [cardinality: 2.1, doc-size: 216.0, op-cost: 0.0, total-cost: 0.0]
+  -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$43] <- [{"A": $$A}] project: [$$43] [cardinality: 2.1, doc-size: 
216.0, op-cost: 0.0, total-cost: 0.0]
+    -- ASSIGN  |PARTITIONED|
+      select (and(eq($$A.getField("f"), 2), lt($$A.getField("g"), 1), 
lt($$A.getField("h"), 1), eq($$A.getField("a"), 0), lt($$44, 4), ge($$44, -1), 
lt($$45, 2500), gt($$45, 2000), lt($$46, 3), gt($$46, 1), le($$47, 4), ge($$47, 
-1))) project: [$$A] [cardinality: 2.1, doc-size: 216.0, op-cost: 0.0, 
total-cost: 0.0]
+      -- STREAM_SELECT  |PARTITIONED|
+        assign [$$47, $$46, $$45, $$44] <- [$$A.getField("b"), 
$$A.getField("c"), $$A.getField("d"), $$A.getField("e")] [cardinality: 2.1, 
doc-size: 216.0, op-cost: 0.0, total-cost: 0.0]
+        -- ASSIGN  |PARTITIONED|
+          project ([$$A]) [cardinality: 2.1, doc-size: 216.0, op-cost: 0.0, 
total-cost: 0.0]
+          -- STREAM_PROJECT  |PARTITIONED|
+            exchange [cardinality: 2.1, doc-size: 216.0, op-cost: 0.0, 
total-cost: 0.0]
+            -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+              unnest-map [$$48, $$A] <- index-search("A", 0, "Default", 
"test", "A", false, false, 1, $$77, 1, $$77, true, true, true) [cardinality: 
2.1, doc-size: 216.0, op-cost: 0.0, total-cost: 0.0]
+              -- BTREE_SEARCH  |PARTITIONED|
+                exchange [cardinality: 0.0, doc-size: 0.0, op-cost: 0.0, 
total-cost: 0.0]
+                -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                  order (ASC, $$77) [cardinality: 0.0, doc-size: 0.0, op-cost: 
0.0, total-cost: 0.0]
+                  -- STABLE_SORT [$$77(ASC)]  |PARTITIONED|
+                    exchange [cardinality: 0.0, doc-size: 0.0, op-cost: 0.0, 
total-cost: 0.0]
+                    -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                      select (and(eq($$72, 2), lt($$73, 1), lt($$74, 1), 
eq($$67, 0), lt($$71, 4), ge($$71, -1), lt($$70, 2500), gt($$70, 2000), 
lt($$69, 3), gt($$69, 1), le($$68, 4), ge($$68, -1))) project: [$$77] 
[cardinality: 0.0, doc-size: 0.0, op-cost: 0.0, total-cost: 0.0]
+                      -- STREAM_SELECT  |PARTITIONED|
+                        project ([$$67, $$68, $$69, $$70, $$71, $$72, $$73, 
$$74, $$77]) [cardinality: 0.0, doc-size: 0.0, op-cost: 0.0, total-cost: 0.0]
+                        -- STREAM_PROJECT  |PARTITIONED|
+                          exchange [cardinality: 0.0, doc-size: 0.0, op-cost: 
0.0, total-cost: 0.0]
+                          -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                            unnest-map [$$67, $$68, $$69, $$70, $$71, $$72, 
$$73, $$74, $$75, $$76, $$77] <- index-search("idx_all", 0, "Default", "test", 
"A", false, false, 6, $$53, $$54, $$55, $$56, $$57, $$58, 8, $$59, $$60, $$61, 
$$62, $$63, $$64, $$65, $$66, true, true, true) [cardinality: 0.0, doc-size: 
0.0, op-cost: 0.0, total-cost: 0.0]
+                            -- BTREE_SEARCH  |PARTITIONED|
+                              exchange [cardinality: 0.0, doc-size: 0.0, 
op-cost: 0.0, total-cost: 0.0]
+                              -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                assign [$$53, $$54, $$55, $$56, $$57, $$58, 
$$59, $$60, $$61, $$62, $$63, $$64, $$65, $$66] <- [0, -1, 1, 2000, -1, 2, 0, 
4, 3, 2500, 4, 2, 1, 1] [cardinality: 0.0, doc-size: 0.0, op-cost: 0.0, 
total-cost: 0.0]
+                                -- ASSIGN  |PARTITIONED|
+                                  empty-tuple-source [cardinality: 0.0, 
doc-size: 0.0, op-cost: 0.0, total-cost: 0.0]
+                                  -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git 
a/asterixdb/asterix-app/src/test/resources/runtimets/results_column/index-only-testcases/simple-index-only-compund-keys/simple-index-only-compund-keys.6.plan
 
b/asterixdb/asterix-app/src/test/resources/runtimets/results_column/index-only-testcases/simple-index-only-compund-keys/simple-index-only-compund-keys.6.plan
index 2d8ec816c8..d78da947da 100644
--- 
a/asterixdb/asterix-app/src/test/resources/runtimets/results_column/index-only-testcases/simple-index-only-compund-keys/simple-index-only-compund-keys.6.plan
+++ 
b/asterixdb/asterix-app/src/test/resources/runtimets/results_column/index-only-testcases/simple-index-only-compund-keys/simple-index-only-compund-keys.6.plan
@@ -1,30 +1,30 @@
-distribute result [$$22] [cardinality: 0.0, doc-size: 0.0, op-cost: 0.0, 
total-cost: 0.0]
+distribute result [$$24] [cardinality: 0.0, doc-size: 0.0, op-cost: 0.0, 
total-cost: 0.0]
 -- DISTRIBUTE_RESULT  |PARTITIONED|
   exchange [cardinality: 0.0, doc-size: 0.0, op-cost: 0.0, total-cost: 0.0]
   -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-    assign [$$22] <- [{"cid": $$23, "orderstatus": $$24, "orderpriority": 
$$26}] project: [$$22] [cardinality: 0.0, doc-size: 0.0, op-cost: 0.0, 
total-cost: 0.0]
+    assign [$$24] <- [{"cid": $$25, "orderstatus": $$26, "orderpriority": 
$$28}] project: [$$24] [cardinality: 0.0, doc-size: 0.0, op-cost: 0.0, 
total-cost: 0.0]
     -- ASSIGN  |PARTITIONED|
-      project ([$$23, $$24, $$26]) [cardinality: 0.0, doc-size: 0.0, op-cost: 
0.0, total-cost: 0.0]
+      project ([$$25, $$26, $$28]) [cardinality: 0.0, doc-size: 0.0, op-cost: 
0.0, total-cost: 0.0]
       -- STREAM_PROJECT  |PARTITIONED|
         exchange [cardinality: 0.0, doc-size: 0.0, op-cost: 0.0, total-cost: 
0.0]
         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-          distinct ([$$31]) [cardinality: 0.0, doc-size: 0.0, op-cost: 0.0, 
total-cost: 0.0]
+          distinct ([$$34]) [cardinality: 0.0, doc-size: 0.0, op-cost: 0.0, 
total-cost: 0.0]
           -- PRE_SORTED_DISTINCT_BY  |PARTITIONED|
             exchange [cardinality: 0.0, doc-size: 0.0, op-cost: 0.0, 
total-cost: 0.0]
             -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-              order (ASC, $$31) [cardinality: 0.0, doc-size: 0.0, op-cost: 
0.0, total-cost: 0.0]
-              -- STABLE_SORT [$$31(ASC)]  |PARTITIONED|
+              order (ASC, $$34) [cardinality: 0.0, doc-size: 0.0, op-cost: 
0.0, total-cost: 0.0]
+              -- STABLE_SORT [$$34(ASC)]  |PARTITIONED|
                 exchange [cardinality: 0.0, doc-size: 0.0, op-cost: 0.0, 
total-cost: 0.0]
                 -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                  select (and(eq($$24, "ORDER_DELIVERED"), lt($$23, 800))) 
[cardinality: 0.0, doc-size: 0.0, op-cost: 0.0, total-cost: 0.0]
+                  select (and(eq($$26, "ORDER_DELIVERED"), lt($$25, 800))) 
[cardinality: 0.0, doc-size: 0.0, op-cost: 0.0, total-cost: 0.0]
                   -- STREAM_SELECT  |PARTITIONED|
                     exchange [cardinality: 0.0, doc-size: 0.0, op-cost: 0.0, 
total-cost: 0.0]
                     -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                      unnest-map [$$23, $$24, $$26, $$31] <- 
index-search("CustomerID_idx", 0, "Default", "test", "Orders", false, false, 0, 
1, $$27, true, true, true) [cardinality: 0.0, doc-size: 0.0, op-cost: 0.0, 
total-cost: 0.0]
+                      unnest-map [$$25, $$26, $$28, $$34] <- 
index-search("CustomerID_idx", 0, "Default", "test", "Orders", false, false, 0, 
2, $$29, $$30, true, true, true) [cardinality: 0.0, doc-size: 0.0, op-cost: 
0.0, total-cost: 0.0]
                       -- BTREE_SEARCH  |PARTITIONED|
                         exchange [cardinality: 0.0, doc-size: 0.0, op-cost: 
0.0, total-cost: 0.0]
                         -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
-                          assign [$$27] <- [800] [cardinality: 0.0, doc-size: 
0.0, op-cost: 0.0, total-cost: 0.0]
+                          assign [$$29, $$30] <- [800, "ORDER_DELIVERED"] 
[cardinality: 0.0, doc-size: 0.0, op-cost: 0.0, total-cost: 0.0]
                           -- ASSIGN  |PARTITIONED|
                             empty-tuple-source [cardinality: 0.0, doc-size: 
0.0, op-cost: 0.0, total-cost: 0.0]
-                            -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
\ No newline at end of file
+                            -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git 
a/asterixdb/asterix-app/src/test/resources/runtimets/results_column/index-selection/btree-index-range/btree-index-range.04.adm
 
b/asterixdb/asterix-app/src/test/resources/runtimets/results_column/index-selection/btree-index-range/btree-index-range.04.adm
new file mode 100644
index 0000000000..17bca478d1
--- /dev/null
+++ 
b/asterixdb/asterix-app/src/test/resources/runtimets/results_column/index-selection/btree-index-range/btree-index-range.04.adm
@@ -0,0 +1,36 @@
+distribute result [$$45] [cardinality: 0.0, doc-size: 0.0, op-cost: 0.0, 
total-cost: 0.0]
+-- DISTRIBUTE_RESULT  |UNPARTITIONED|
+  exchange [cardinality: 0.0, doc-size: 0.0, op-cost: 0.0, total-cost: 0.0]
+  -- ONE_TO_ONE_EXCHANGE  |UNPARTITIONED|
+    assign [$$45] <- [{"$1": $$47}] project: [$$45] [cardinality: 0.0, 
doc-size: 0.0, op-cost: 0.0, total-cost: 0.0]
+    -- ASSIGN  |UNPARTITIONED|
+      aggregate [$$47] <- [agg-sql-sum($$51)] [cardinality: 0.0, doc-size: 
0.0, op-cost: 0.0, total-cost: 0.0]
+      -- AGGREGATE  |UNPARTITIONED|
+        exchange [cardinality: 0.0, doc-size: 0.0, op-cost: 0.0, total-cost: 
0.0]
+        -- RANDOM_MERGE_EXCHANGE  |PARTITIONED|
+          aggregate [$$51] <- [agg-sql-count(1)] [cardinality: 0.0, doc-size: 
0.0, op-cost: 0.0, total-cost: 0.0]
+          -- AGGREGATE  |PARTITIONED|
+            exchange [cardinality: 0.0, doc-size: 0.0, op-cost: 0.0, 
total-cost: 0.0]
+            -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+              distinct ([$$60]) [cardinality: 0.0, doc-size: 0.0, op-cost: 
0.0, total-cost: 0.0]
+              -- PRE_SORTED_DISTINCT_BY  |PARTITIONED|
+                exchange [cardinality: 0.0, doc-size: 0.0, op-cost: 0.0, 
total-cost: 0.0]
+                -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                  order (ASC, $$60) [cardinality: 0.0, doc-size: 0.0, op-cost: 
0.0, total-cost: 0.0]
+                  -- STABLE_SORT [$$60(ASC)]  |PARTITIONED|
+                    exchange [cardinality: 0.0, doc-size: 0.0, op-cost: 0.0, 
total-cost: 0.0]
+                    -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                      select (and(eq($$50, 1), gt($$49, 0), gt($$48, 2))) 
project: [$$60] [cardinality: 0.0, doc-size: 0.0, op-cost: 0.0, total-cost: 0.0]
+                      -- STREAM_SELECT  |PARTITIONED|
+                        project ([$$50, $$49, $$48, $$60]) [cardinality: 0.0, 
doc-size: 0.0, op-cost: 0.0, total-cost: 0.0]
+                        -- STREAM_PROJECT  |PARTITIONED|
+                          exchange [cardinality: 0.0, doc-size: 0.0, op-cost: 
0.0, total-cost: 0.0]
+                          -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                            unnest-map [$$50, $$49, $$48, $$59, $$60] <- 
index-search("idx_abcd", 0, "Default", "test", "A", false, false, 3, $$52, 
$$53, $$54, 1, $$55, true, true, true) [cardinality: 0.0, doc-size: 0.0, 
op-cost: 0.0, total-cost: 0.0]
+                            -- BTREE_SEARCH  |PARTITIONED|
+                              exchange [cardinality: 0.0, doc-size: 0.0, 
op-cost: 0.0, total-cost: 0.0]
+                              -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                assign [$$52, $$53, $$54, $$55] <- [1, 0, 2, 
1] [cardinality: 0.0, doc-size: 0.0, op-cost: 0.0, total-cost: 0.0]
+                                -- ASSIGN  |PARTITIONED|
+                                  empty-tuple-source [cardinality: 0.0, 
doc-size: 0.0, op-cost: 0.0, total-cost: 0.0]
+                                  -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git 
a/asterixdb/asterix-app/src/test/resources/runtimets/results_column/index-selection/btree-index-range/btree-index-range.06.adm
 
b/asterixdb/asterix-app/src/test/resources/runtimets/results_column/index-selection/btree-index-range/btree-index-range.06.adm
new file mode 100644
index 0000000000..362e49007c
--- /dev/null
+++ 
b/asterixdb/asterix-app/src/test/resources/runtimets/results_column/index-selection/btree-index-range/btree-index-range.06.adm
@@ -0,0 +1,34 @@
+distribute result [$$50] [cardinality: 0.0, doc-size: 0.0, op-cost: 0.0, 
total-cost: 0.0]
+-- DISTRIBUTE_RESULT  |UNPARTITIONED|
+  exchange [cardinality: 0.0, doc-size: 0.0, op-cost: 0.0, total-cost: 0.0]
+  -- ONE_TO_ONE_EXCHANGE  |UNPARTITIONED|
+    assign [$$50] <- [{"$1": $$53}] project: [$$50] [cardinality: 0.0, 
doc-size: 0.0, op-cost: 0.0, total-cost: 0.0]
+    -- ASSIGN  |UNPARTITIONED|
+      aggregate [$$53] <- [agg-sql-sum($$57)] [cardinality: 0.0, doc-size: 
0.0, op-cost: 0.0, total-cost: 0.0]
+      -- AGGREGATE  |UNPARTITIONED|
+        exchange [cardinality: 0.0, doc-size: 0.0, op-cost: 0.0, total-cost: 
0.0]
+        -- RANDOM_MERGE_EXCHANGE  |PARTITIONED|
+          aggregate [$$57] <- [agg-sql-count(1)] [cardinality: 0.0, doc-size: 
0.0, op-cost: 0.0, total-cost: 0.0]
+          -- AGGREGATE  |PARTITIONED|
+            exchange [cardinality: 0.0, doc-size: 0.0, op-cost: 0.0, 
total-cost: 0.0]
+            -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+              distinct ([$$67]) [cardinality: 0.0, doc-size: 0.0, op-cost: 
0.0, total-cost: 0.0]
+              -- PRE_SORTED_DISTINCT_BY  |PARTITIONED|
+                exchange [cardinality: 0.0, doc-size: 0.0, op-cost: 0.0, 
total-cost: 0.0]
+                -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                  order (ASC, $$67) [cardinality: 0.0, doc-size: 0.0, op-cost: 
0.0, total-cost: 0.0]
+                  -- STABLE_SORT [$$67(ASC)]  |PARTITIONED|
+                    exchange [cardinality: 0.0, doc-size: 0.0, op-cost: 0.0, 
total-cost: 0.0]
+                    -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                      select (and(gt($$56, 2), le($$55, 6000), eq($$54, 0), 
le($$51, 3), ge($$51, 1))) project: [$$67] [cardinality: 0.0, doc-size: 0.0, 
op-cost: 0.0, total-cost: 0.0]
+                      -- STREAM_SELECT  |PARTITIONED|
+                        exchange [cardinality: 0.0, doc-size: 0.0, op-cost: 
0.0, total-cost: 0.0]
+                        -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                          unnest-map [$$54, $$51, $$56, $$55, $$67] <- 
index-search("idx_abcd", 0, "Default", "test", "A", false, false, 3, $$58, 
$$59, $$60, 2, $$61, $$62, true, true, true) [cardinality: 0.0, doc-size: 0.0, 
op-cost: 0.0, total-cost: 0.0]
+                          -- BTREE_SEARCH  |PARTITIONED|
+                            exchange [cardinality: 0.0, doc-size: 0.0, 
op-cost: 0.0, total-cost: 0.0]
+                            -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                              assign [$$58, $$59, $$60, $$61, $$62] <- [0, 1, 
2, 0, 3] [cardinality: 0.0, doc-size: 0.0, op-cost: 0.0, total-cost: 0.0]
+                              -- ASSIGN  |PARTITIONED|
+                                empty-tuple-source [cardinality: 0.0, 
doc-size: 0.0, op-cost: 0.0, total-cost: 0.0]
+                                -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git 
a/asterixdb/asterix-app/src/test/resources/runtimets/results_column/index-selection/btree-index-range/btree-index-range.08.adm
 
b/asterixdb/asterix-app/src/test/resources/runtimets/results_column/index-selection/btree-index-range/btree-index-range.08.adm
new file mode 100644
index 0000000000..eb49f3b47d
--- /dev/null
+++ 
b/asterixdb/asterix-app/src/test/resources/runtimets/results_column/index-selection/btree-index-range/btree-index-range.08.adm
@@ -0,0 +1,36 @@
+distribute result [$$45] [cardinality: 0.0, doc-size: 0.0, op-cost: 0.0, 
total-cost: 0.0]
+-- DISTRIBUTE_RESULT  |UNPARTITIONED|
+  exchange [cardinality: 0.0, doc-size: 0.0, op-cost: 0.0, total-cost: 0.0]
+  -- ONE_TO_ONE_EXCHANGE  |UNPARTITIONED|
+    assign [$$45] <- [{"$1": $$47}] project: [$$45] [cardinality: 0.0, 
doc-size: 0.0, op-cost: 0.0, total-cost: 0.0]
+    -- ASSIGN  |UNPARTITIONED|
+      aggregate [$$47] <- [agg-sql-sum($$51)] [cardinality: 0.0, doc-size: 
0.0, op-cost: 0.0, total-cost: 0.0]
+      -- AGGREGATE  |UNPARTITIONED|
+        exchange [cardinality: 0.0, doc-size: 0.0, op-cost: 0.0, total-cost: 
0.0]
+        -- RANDOM_MERGE_EXCHANGE  |PARTITIONED|
+          aggregate [$$51] <- [agg-sql-count(1)] [cardinality: 0.0, doc-size: 
0.0, op-cost: 0.0, total-cost: 0.0]
+          -- AGGREGATE  |PARTITIONED|
+            exchange [cardinality: 0.0, doc-size: 0.0, op-cost: 0.0, 
total-cost: 0.0]
+            -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+              distinct ([$$60]) [cardinality: 0.0, doc-size: 0.0, op-cost: 
0.0, total-cost: 0.0]
+              -- PRE_SORTED_DISTINCT_BY  |PARTITIONED|
+                exchange [cardinality: 0.0, doc-size: 0.0, op-cost: 0.0, 
total-cost: 0.0]
+                -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                  order (ASC, $$60) [cardinality: 0.0, doc-size: 0.0, op-cost: 
0.0, total-cost: 0.0]
+                  -- STABLE_SORT [$$60(ASC)]  |PARTITIONED|
+                    exchange [cardinality: 0.0, doc-size: 0.0, op-cost: 0.0, 
total-cost: 0.0]
+                    -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                      select (and(eq($$50, 1), lt($$49, 2), lt($$48, 4))) 
project: [$$60] [cardinality: 0.0, doc-size: 0.0, op-cost: 0.0, total-cost: 0.0]
+                      -- STREAM_SELECT  |PARTITIONED|
+                        project ([$$50, $$49, $$48, $$60]) [cardinality: 0.0, 
doc-size: 0.0, op-cost: 0.0, total-cost: 0.0]
+                        -- STREAM_PROJECT  |PARTITIONED|
+                          exchange [cardinality: 0.0, doc-size: 0.0, op-cost: 
0.0, total-cost: 0.0]
+                          -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                            unnest-map [$$50, $$49, $$48, $$59, $$60] <- 
index-search("idx_abcd", 0, "Default", "test", "A", false, false, 1, $$52, 3, 
$$53, $$54, $$55, true, true, true) [cardinality: 0.0, doc-size: 0.0, op-cost: 
0.0, total-cost: 0.0]
+                            -- BTREE_SEARCH  |PARTITIONED|
+                              exchange [cardinality: 0.0, doc-size: 0.0, 
op-cost: 0.0, total-cost: 0.0]
+                              -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                assign [$$52, $$53, $$54, $$55] <- [1, 1, 2, 
4] [cardinality: 0.0, doc-size: 0.0, op-cost: 0.0, total-cost: 0.0]
+                                -- ASSIGN  |PARTITIONED|
+                                  empty-tuple-source [cardinality: 0.0, 
doc-size: 0.0, op-cost: 0.0, total-cost: 0.0]
+                                  -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git 
a/asterixdb/asterix-app/src/test/resources/runtimets/results_column/index-selection/btree-index-range/btree-index-range.10.adm
 
b/asterixdb/asterix-app/src/test/resources/runtimets/results_column/index-selection/btree-index-range/btree-index-range.10.adm
new file mode 100644
index 0000000000..5c7b930944
--- /dev/null
+++ 
b/asterixdb/asterix-app/src/test/resources/runtimets/results_column/index-selection/btree-index-range/btree-index-range.10.adm
@@ -0,0 +1,36 @@
+distribute result [$$43] [cardinality: 0.0, doc-size: 0.0, op-cost: 0.0, 
total-cost: 0.0]
+-- DISTRIBUTE_RESULT  |PARTITIONED|
+  exchange [cardinality: 0.0, doc-size: 0.0, op-cost: 0.0, total-cost: 0.0]
+  -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+    assign [$$43] <- [{"A": $$A}] project: [$$43] [cardinality: 0.0, doc-size: 
0.0, op-cost: 0.0, total-cost: 0.0]
+    -- ASSIGN  |PARTITIONED|
+      select (and(eq($$A.getField("f"), 2), lt($$A.getField("g"), 1), 
lt($$A.getField("h"), 1), eq($$A.getField("a"), 0), lt($$44, 4), ge($$44, -1), 
lt($$45, 2500), gt($$45, 2000), lt($$46, 3), gt($$46, 1), le($$47, 4), ge($$47, 
-1))) project: [$$A] [cardinality: 0.0, doc-size: 0.0, op-cost: 0.0, 
total-cost: 0.0]
+      -- STREAM_SELECT  |PARTITIONED|
+        assign [$$47, $$46, $$45, $$44] <- [$$A.getField("b"), 
$$A.getField("c"), $$A.getField("d"), $$A.getField("e")] [cardinality: 0.0, 
doc-size: 0.0, op-cost: 0.0, total-cost: 0.0]
+        -- ASSIGN  |PARTITIONED|
+          project ([$$A]) [cardinality: 0.0, doc-size: 0.0, op-cost: 0.0, 
total-cost: 0.0]
+          -- STREAM_PROJECT  |PARTITIONED|
+            exchange [cardinality: 0.0, doc-size: 0.0, op-cost: 0.0, 
total-cost: 0.0]
+            -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+              unnest-map [$$48, $$A] <- index-search("A", 0, "Default", 
"test", "A", false, false, 1, $$77, 1, $$77, true, true, true) range-filter on: 
and(eq($$A.getField("f"), 2), lt($$A.getField("g"), 1), lt($$A.getField("h"), 
1), eq($$A.getField("a"), 0), lt($$A.getField("e"), 4), ge($$A.getField("e"), 
-1), lt($$A.getField("d"), 2500), gt($$A.getField("d"), 2000), 
lt($$A.getField("c"), 3), gt($$A.getField("c"), 1), le($$A.getField("b"), 4), 
ge($$A.getField("b"), -1)) [cardinality: 0. [...]
+              -- BTREE_SEARCH  |PARTITIONED|
+                exchange [cardinality: 0.0, doc-size: 0.0, op-cost: 0.0, 
total-cost: 0.0]
+                -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                  order (ASC, $$77) [cardinality: 0.0, doc-size: 0.0, op-cost: 
0.0, total-cost: 0.0]
+                  -- STABLE_SORT [$$77(ASC)]  |PARTITIONED|
+                    exchange [cardinality: 0.0, doc-size: 0.0, op-cost: 0.0, 
total-cost: 0.0]
+                    -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                      select (and(eq($$72, 2), lt($$73, 1), lt($$74, 1), 
eq($$67, 0), lt($$71, 4), ge($$71, -1), lt($$70, 2500), gt($$70, 2000), 
lt($$69, 3), gt($$69, 1), le($$68, 4), ge($$68, -1))) project: [$$77] 
[cardinality: 0.0, doc-size: 0.0, op-cost: 0.0, total-cost: 0.0]
+                      -- STREAM_SELECT  |PARTITIONED|
+                        project ([$$67, $$68, $$69, $$70, $$71, $$72, $$73, 
$$74, $$77]) [cardinality: 0.0, doc-size: 0.0, op-cost: 0.0, total-cost: 0.0]
+                        -- STREAM_PROJECT  |PARTITIONED|
+                          exchange [cardinality: 0.0, doc-size: 0.0, op-cost: 
0.0, total-cost: 0.0]
+                          -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                            unnest-map [$$67, $$68, $$69, $$70, $$71, $$72, 
$$73, $$74, $$75, $$76, $$77] <- index-search("idx_all", 0, "Default", "test", 
"A", false, false, 6, $$53, $$54, $$55, $$56, $$57, $$58, 8, $$59, $$60, $$61, 
$$62, $$63, $$64, $$65, $$66, true, true, true) [cardinality: 0.0, doc-size: 
0.0, op-cost: 0.0, total-cost: 0.0]
+                            -- BTREE_SEARCH  |PARTITIONED|
+                              exchange [cardinality: 0.0, doc-size: 0.0, 
op-cost: 0.0, total-cost: 0.0]
+                              -- ONE_TO_ONE_EXCHANGE  |PARTITIONED|
+                                assign [$$53, $$54, $$55, $$56, $$57, $$58, 
$$59, $$60, $$61, $$62, $$63, $$64, $$65, $$66] <- [0, -1, 1, 2000, -1, 2, 0, 
4, 3, 2500, 4, 2, 1, 1] [cardinality: 0.0, doc-size: 0.0, op-cost: 0.0, 
total-cost: 0.0]
+                                -- ASSIGN  |PARTITIONED|
+                                  empty-tuple-source [cardinality: 0.0, 
doc-size: 0.0, op-cost: 0.0, total-cost: 0.0]
+                                  -- EMPTY_TUPLE_SOURCE  |PARTITIONED|
diff --git 
a/asterixdb/asterix-app/src/test/resources/runtimets/sqlpp_queries.xml 
b/asterixdb/asterix-app/src/test/resources/runtimets/sqlpp_queries.xml
index f8d415b1fc..c75cabb232 100644
--- a/asterixdb/asterix-app/src/test/resources/runtimets/sqlpp_queries.xml
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/sqlpp_queries.xml
@@ -6432,6 +6432,11 @@
         <output-dir compare="Text">batch-lookup</output-dir>
       </compilation-unit>
     </test-case>
+    <test-case FilePath="index-selection">
+      <compilation-unit name="btree-index-range">
+        <output-dir compare="Text">btree-index-range</output-dir>
+      </compilation-unit>
+    </test-case>
     <test-case FilePath="index-selection">
       <compilation-unit name="btree-index-composite-key">
         <output-dir compare="Text">btree-index-composite-key</output-dir>


Reply via email to