Merge "Merge branch 'trinity' into 'master'"
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 fd65e5d..defb383 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
@@ -453,10 +453,16 @@
                     dest.addAll(KeyFieldTypeUtil.getArrayBTreeIndexKeyTypes(index, recordType, metaRecordType));
                     break;
                 case BTREE:
-                    //TODO(ali): check if types should be made nullable/missable
                     List<Pair<IAType, Boolean>> bTreeIndexKeyTypes =
                             KeyFieldTypeUtil.getBTreeIndexKeyTypes(index, recordType, metaRecordType);
-                    dest.addAll(bTreeIndexKeyTypes.stream().map(Pair::getFirst).collect(Collectors.toList()));
+                    boolean overridingKeyFieldTypes = index.getIndexDetails().isOverridingKeyFieldTypes();
+                    for (int i = 0; i < bTreeIndexKeyTypes.size(); i++) {
+                        if (bTreeIndexKeyTypes.get(i).second || overridingKeyFieldTypes) {
+                            dest.add(AUnionType.createUnknownableType(bTreeIndexKeyTypes.get(i).first));
+                        } else {
+                            dest.add(bTreeIndexKeyTypes.get(i).first);
+                        }
+                    }
                     break;
                 case RTREE:
                     dest.addAll(KeyFieldTypeUtil.getRTreeIndexKeyTypes(index, recordType, metaRecordType));
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/index-selection/btree-index-composite-key-04/btree-index-composite-key-04.1.ddl.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/index-selection/btree-index-composite-key-04/btree-index-composite-key-04.1.ddl.sqlpp
index a0fc289..89d5e2e 100644
--- a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/index-selection/btree-index-composite-key-04/btree-index-composite-key-04.1.ddl.sqlpp
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/index-selection/btree-index-composite-key-04/btree-index-composite-key-04.1.ddl.sqlpp
@@ -36,6 +36,13 @@
   lname : string?
 };
 
-create dataset employee(Emp) primary key id;
+create type test.EmpOpen as
+{
+  id : bigint
+};
 
-create index idx_employee_f_l_name on employee (fname,lname) type btree;
\ No newline at end of file
+create dataset employee(Emp) primary key id;
+create dataset employeeOpen(EmpOpen) primary key id;
+
+create index idx_employee_f_l_name on employee (fname,lname) type btree;
+create index idx_employee_f_l_name on employeeOpen (fname: string, lname: string) type btree;
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/index-selection/btree-index-composite-key-04/btree-index-composite-key-04.2.update.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/index-selection/btree-index-composite-key-04/btree-index-composite-key-04.2.update.sqlpp
index 3563057..fa45a86 100644
--- a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/index-selection/btree-index-composite-key-04/btree-index-composite-key-04.2.update.sqlpp
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/index-selection/btree-index-composite-key-04/btree-index-composite-key-04.2.update.sqlpp
@@ -40,3 +40,28 @@
     "fname": "B",
     "lname": "Y"
 });
+insert into employee ({
+    "id": 4,
+    "fname": "C"
+    /* "lname" is missing */
+});
+insert into employeeOpen ({
+    "id": 1,
+    "fname": "A",
+    "lname": "X"
+});
+insert into employeeOpen ({
+    "id": 2,
+    "fname": "A"
+    /* "lname" is missing */
+});
+insert into employeeOpen ({
+    "id": 3,
+    "fname": "B",
+    "lname": "Y"
+});
+insert into employeeOpen ({
+    "id": 4,
+    "fname": "C"
+    /* "lname" is missing */
+});
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/index-selection/btree-index-composite-key-04/btree-index-composite-key-04.4.query.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/index-selection/btree-index-composite-key-04/btree-index-composite-key-04.4.query.sqlpp
new file mode 100644
index 0000000..efc0518
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/index-selection/btree-index-composite-key-04/btree-index-composite-key-04.4.query.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     : Define BTree index on a composite key (fname,lname?)
+ *                 : Query predicate => where fname="..."
+ *                 : Currently this index cannot be used for this query because
+ *                 : the index will not store composite keys where some fields are NULL/MISSING.
+ * Expected Result : Success
+ */
+
+use test;
+
+select id, fname, lname
+from employee
+where fname = "C";
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/index-selection/btree-index-composite-key-04/btree-index-composite-key-04.5.query.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/index-selection/btree-index-composite-key-04/btree-index-composite-key-04.5.query.sqlpp
new file mode 100644
index 0000000..edd6cbc
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/index-selection/btree-index-composite-key-04/btree-index-composite-key-04.5.query.sqlpp
@@ -0,0 +1,32 @@
+/*
+ * 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     : Define BTree index on a composite key (fname,lname?)
+ *                 : Query predicate => where fname="..."
+ *                 : Currently this index cannot be used for this query because
+ *                 : the index will not store composite keys where some fields are NULL/MISSING.
+ * Expected Result : Success
+ */
+
+use test;
+
+select id, fname, lname
+from employeeOpen
+where fname = "A"
+order by id
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/index-selection/btree-index-composite-key-04/btree-index-composite-key-04.6.query.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/index-selection/btree-index-composite-key-04/btree-index-composite-key-04.6.query.sqlpp
new file mode 100644
index 0000000..e23647d
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/index-selection/btree-index-composite-key-04/btree-index-composite-key-04.6.query.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     : Define BTree index on a composite key (fname,lname?)
+ *                 : Query predicate => where fname="..."
+ *                 : Currently this index cannot be used for this query because
+ *                 : the index will not store composite keys where some fields are NULL/MISSING.
+ * Expected Result : Success
+ */
+
+use test;
+
+select id, fname, lname
+from employeeOpen
+where fname = "C";
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/results/index-selection/btree-index-composite-key-04/btree-index-composite-key-04.4.adm b/asterixdb/asterix-app/src/test/resources/runtimets/results/index-selection/btree-index-composite-key-04/btree-index-composite-key-04.4.adm
new file mode 100644
index 0000000..e663d03
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/results/index-selection/btree-index-composite-key-04/btree-index-composite-key-04.4.adm
@@ -0,0 +1 @@
+{ "id": 4, "fname": "C" }
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/results/index-selection/btree-index-composite-key-04/btree-index-composite-key-04.5.adm b/asterixdb/asterix-app/src/test/resources/runtimets/results/index-selection/btree-index-composite-key-04/btree-index-composite-key-04.5.adm
new file mode 100644
index 0000000..f853208
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/results/index-selection/btree-index-composite-key-04/btree-index-composite-key-04.5.adm
@@ -0,0 +1,2 @@
+{ "id": 1, "fname": "A", "lname": "X" }
+{ "id": 2, "fname": "A" }
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/results/index-selection/btree-index-composite-key-04/btree-index-composite-key-04.6.adm b/asterixdb/asterix-app/src/test/resources/runtimets/results/index-selection/btree-index-composite-key-04/btree-index-composite-key-04.6.adm
new file mode 100644
index 0000000..e663d03
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/results/index-selection/btree-index-composite-key-04/btree-index-composite-key-04.6.adm
@@ -0,0 +1 @@
+{ "id": 4, "fname": "C" }
diff --git a/asterixdb/asterix-metadata/src/main/java/org/apache/asterix/metadata/entities/Index.java b/asterixdb/asterix-metadata/src/main/java/org/apache/asterix/metadata/entities/Index.java
index 963b3ff..cb9a090 100644
--- a/asterixdb/asterix-metadata/src/main/java/org/apache/asterix/metadata/entities/Index.java
+++ b/asterixdb/asterix-metadata/src/main/java/org/apache/asterix/metadata/entities/Index.java
@@ -156,6 +156,7 @@
     public static Pair<IAType, Boolean> getNonNullableType(IAType keyType) {
         boolean nullable = false;
         IAType actualKeyType = keyType;
+        // check open field whose type is ANY?
         if (NonTaggedFormatUtil.isOptional(keyType)) {
             actualKeyType = ((AUnionType) keyType).getActualType();
             nullable = true;
@@ -165,6 +166,7 @@
 
     public static Pair<IAType, Boolean> getNonNullableOpenFieldType(Index index, IAType fieldType,
             List<String> fieldName, ARecordType recType) throws AlgebricksException {
+        // check open field whose type is ANY?
         if (IndexUtil.castDefaultNull(index)) {
             Pair<IAType, Boolean> nonNullableType = getNonNullableType(fieldType);
             nonNullableType.second = true;
@@ -199,6 +201,7 @@
     public static Pair<IAType, Boolean> getNonNullableKeyFieldType(List<String> expr, ARecordType recType)
             throws AlgebricksException {
         IAType keyType = Index.keyFieldType(expr, recType);
+        // check open field whose type is ANY?
         Pair<IAType, Boolean> pair = getNonNullableType(keyType);
         pair.second = pair.second || recType.isSubFieldNullable(expr);
         return pair;