>From Ali Alsuliman <[email protected]>:

Ali Alsuliman has uploaded this change for review. ( 
https://asterix-gerrit.ics.uci.edu/c/asterixdb/+/21173?usp=email )


Change subject: [ASTERIXDB-3765][COMP] Fix OBJECT_PUT/ADD() type computers
......................................................................

[ASTERIXDB-3765][COMP] Fix OBJECT_PUT/ADD() type computers

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

Details:
Fields with type ANY should not be part of the schema of
the record type computed by OBJECT_PUT/ADD().
Don't add fields with type ANY to the record type schema.
Instead the record type should be made open to accept such
fields in the open part of the record.

Ext-ref: MB-70896
Change-Id: Ieb3f6ed85c107ff849e34850a15505ea61fbb4eb
---
M 
asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/objects/ObjectsQueries.xml
A 
asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/objects/object_mod/object_mod.1.ddl.sqlpp
A 
asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/objects/object_mod/object_mod.2.update.sqlpp
A 
asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/objects/object_mod/object_mod.3.query.sqlpp
A 
asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/objects/object_mod/object_put.4.ddl.sqlpp
A 
asterixdb/asterix-app/src/test/resources/runtimets/results/objects/object_mod/object_mod.3.adm
M 
asterixdb/asterix-om/src/main/java/org/apache/asterix/om/typecomputer/impl/AbstractRecordFunctionTypeComputer.java
M 
asterixdb/asterix-om/src/main/java/org/apache/asterix/om/typecomputer/impl/RecordAddTypeComputer.java
M 
asterixdb/asterix-om/src/main/java/org/apache/asterix/om/typecomputer/impl/RecordPutTypeComputer.java
M 
asterixdb/asterix-om/src/main/java/org/apache/asterix/om/typecomputer/impl/RecordRemoveTypeComputer.java
M 
asterixdb/asterix-om/src/main/java/org/apache/asterix/om/typecomputer/impl/RecordRenameTypeComputer.java
11 files changed, 186 insertions(+), 32 deletions(-)



  git pull ssh://asterix-gerrit.ics.uci.edu:29418/asterixdb 
refs/changes/73/21173/1

diff --git 
a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/objects/ObjectsQueries.xml
 
b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/objects/ObjectsQueries.xml
index 4f8ac79..3e94601 100644
--- 
a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/objects/ObjectsQueries.xml
+++ 
b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/objects/ObjectsQueries.xml
@@ -161,6 +161,11 @@
     </compilation-unit>
   </test-case>
   <test-case FilePath="objects">
+    <compilation-unit name="object_mod">
+      <output-dir compare="Text">object_mod</output-dir>
+    </compilation-unit>
+  </test-case>
+  <test-case FilePath="objects">
     <compilation-unit name="object_names">
       <output-dir compare="Text">object_names</output-dir>
     </compilation-unit>
diff --git 
a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/objects/object_mod/object_mod.1.ddl.sqlpp
 
b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/objects/object_mod/object_mod.1.ddl.sqlpp
new file mode 100644
index 0000000..771c9d0
--- /dev/null
+++ 
b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/objects/object_mod/object_mod.1.ddl.sqlpp
@@ -0,0 +1,36 @@
+/*
+ * 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  : Testing object_put/add with values being added to open and 
closed parts of the record.
+ * Expected Res : Success
+ */
+
+DROP DATAVERSE TestDataverse IF EXISTS;
+CREATE DATAVERSE TestDataverse;
+
+USE TestDataverse;
+
+CREATE TYPE TestDataverse.TestType AS {
+  id: int,
+  closed_int_field: int,
+  closed_str_field: string
+};
+
+CREATE DATASET TestDataverse.TestDataset(TestDataverse.TestType) PRIMARY KEY 
id;
\ No newline at end of file
diff --git 
a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/objects/object_mod/object_mod.2.update.sqlpp
 
b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/objects/object_mod/object_mod.2.update.sqlpp
new file mode 100644
index 0000000..0477ece
--- /dev/null
+++ 
b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/objects/object_mod/object_mod.2.update.sqlpp
@@ -0,0 +1,24 @@
+/*
+ * 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.
+ */
+
+USE TestDataverse;
+INSERT INTO TestDataset([
+{ "id": 1, "closed_int_field": 10, "closed_str_field": "abc", 
"open_int_field": 100, "open_str_field": "def" }
+]
+);
\ No newline at end of file
diff --git 
a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/objects/object_mod/object_mod.3.query.sqlpp
 
b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/objects/object_mod/object_mod.3.query.sqlpp
new file mode 100644
index 0000000..c286c7f
--- /dev/null
+++ 
b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/objects/object_mod/object_mod.3.query.sqlpp
@@ -0,0 +1,53 @@
+/*
+ * 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.
+ */
+
+USE TestDataverse;
+
+SELECT
+OBJECT_PUT(t, "from_closed_int_field", t.closed_int_field) AS 
put_from_closed_int_field,
+OBJECT_PUT(t, "from_closed_str_field", t.closed_str_field) AS 
put_from_closed_str_field,
+OBJECT_PUT(t, "from_open_int_field", t.open_int_field) AS 
put_from_open_int_field,
+OBJECT_PUT(t, "from_open_str_field", t.open_str_field) AS 
put_from_open_str_field,
+
+OBJECT_PUT(t, "closed_int_field", t.closed_str_field) AS 
put_from_closed_str_field_to_closed_int_field,
+OBJECT_PUT(t, "closed_str_field", t.closed_int_field) AS 
put_from_closed_int_field_to_closed_str_field,
+OBJECT_PUT(t, "open_int_field", t.open_str_field) AS 
put_from_open_str_field_to_open_int_field,
+OBJECT_PUT(t, "open_str_field", t.open_int_field) AS 
put_from_open_int_field_to_open_str_field,
+
+OBJECT_PUT(t, "closed_int_field", t.open_int_field) AS 
put_from_open_int_field_to_closed_int_field,
+OBJECT_PUT(t, "closed_str_field", t.open_str_field) AS 
put_from_open_str_field_to_closed_str_field,
+OBJECT_PUT(t, "open_int_field", t.closed_int_field) AS 
put_from_closed_int_field_to_open_int_field,
+OBJECT_PUT(t, "open_str_field", t.closed_str_field) AS 
put_from_closed_str_field_to_open_str_field,
+
+OBJECT_ADD(t, "from_closed_int_field", t.closed_int_field) AS 
add_from_closed_int_field,
+OBJECT_ADD(t, "from_closed_str_field", t.closed_str_field) AS 
add_from_closed_str_field,
+OBJECT_ADD(t, "from_open_int_field", t.open_int_field) AS 
add_from_open_int_field,
+OBJECT_ADD(t, "from_open_str_field", t.open_str_field) AS 
add_from_open_str_field,
+
+OBJECT_ADD(t, "closed_int_field", t.closed_str_field) AS 
add_from_closed_str_field_to_closed_int_field,
+OBJECT_ADD(t, "closed_str_field", t.closed_int_field) AS 
add_from_closed_int_field_to_closed_str_field,
+OBJECT_ADD(t, "open_int_field", t.open_str_field) AS 
add_from_open_str_field_to_open_int_field,
+OBJECT_ADD(t, "open_str_field", t.open_int_field) AS 
add_from_open_int_field_to_open_str_field,
+
+OBJECT_ADD(t, "closed_int_field", t.open_int_field) AS 
add_from_open_int_field_to_closed_int_field,
+OBJECT_ADD(t, "closed_str_field", t.open_str_field) AS 
add_from_open_str_field_to_closed_str_field,
+OBJECT_ADD(t, "open_int_field", t.closed_int_field) AS 
add_from_closed_int_field_to_open_int_field,
+OBJECT_ADD(t, "open_str_field", t.closed_str_field) AS 
add_from_closed_str_field_to_open_str_field
+
+FROM TestDataset AS t;
\ No newline at end of file
diff --git 
a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/objects/object_mod/object_put.4.ddl.sqlpp
 
b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/objects/object_mod/object_put.4.ddl.sqlpp
new file mode 100644
index 0000000..bd8b62c
--- /dev/null
+++ 
b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/objects/object_mod/object_put.4.ddl.sqlpp
@@ -0,0 +1,20 @@
+/*
+ * 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.
+ */
+
+DROP DATAVERSE TestDataverse IF EXISTS;
\ No newline at end of file
diff --git 
a/asterixdb/asterix-app/src/test/resources/runtimets/results/objects/object_mod/object_mod.3.adm
 
b/asterixdb/asterix-app/src/test/resources/runtimets/results/objects/object_mod/object_mod.3.adm
new file mode 100644
index 0000000..6f4b590
--- /dev/null
+++ 
b/asterixdb/asterix-app/src/test/resources/runtimets/results/objects/object_mod/object_mod.3.adm
@@ -0,0 +1 @@
+{ "put_from_closed_int_field": { "id": 1, "closed_int_field": 10, 
"closed_str_field": "abc", "from_closed_int_field": 10, "open_int_field": 100, 
"open_str_field": "def" }, "put_from_closed_str_field": { "id": 1, 
"closed_int_field": 10, "closed_str_field": "abc", "from_closed_str_field": 
"abc", "open_int_field": 100, "open_str_field": "def" }, 
"put_from_open_int_field": { "id": 1, "closed_int_field": 10, 
"closed_str_field": "abc", "open_int_field": 100, "open_str_field": "def", 
"from_open_int_field": 100 }, "put_from_open_str_field": { "id": 1, 
"closed_int_field": 10, "closed_str_field": "abc", "open_int_field": 100, 
"open_str_field": "def", "from_open_str_field": "def" }, 
"put_from_closed_str_field_to_closed_int_field": { "id": 1, "closed_int_field": 
"abc", "closed_str_field": "abc", "open_int_field": 100, "open_str_field": 
"def" }, "put_from_closed_int_field_to_closed_str_field": { "id": 1, 
"closed_int_field": 10, "closed_str_field": 10, "open_int_field": 100, 
"open_str_field": "def" }, "put_from_open_str_field_to_open_int_field": { "id": 
1, "closed_int_field": 10, "closed_str_field": "abc", "open_int_field": "def", 
"open_str_field": "def" }, "put_from_open_int_field_to_open_str_field": { "id": 
1, "closed_int_field": 10, "closed_str_field": "abc", "open_int_field": 100, 
"open_str_field": 100 }, "put_from_open_int_field_to_closed_int_field": { "id": 
1, "closed_str_field": "abc", "closed_int_field": 100, "open_int_field": 100, 
"open_str_field": "def" }, "put_from_open_str_field_to_closed_str_field": { 
"id": 1, "closed_int_field": 10, "closed_str_field": "def", "open_int_field": 
100, "open_str_field": "def" }, "put_from_closed_int_field_to_open_int_field": 
{ "id": 1, "closed_int_field": 10, "closed_str_field": "abc", "open_int_field": 
10, "open_str_field": "def" }, "put_from_closed_str_field_to_open_str_field": { 
"id": 1, "closed_int_field": 10, "closed_str_field": "abc", "open_str_field": 
"abc", "open_int_field": 100 }, "add_from_closed_int_field": { "id": 1, 
"closed_int_field": 10, "closed_str_field": "abc", "from_closed_int_field": 10, 
"open_int_field": 100, "open_str_field": "def" }, "add_from_closed_str_field": 
{ "id": 1, "closed_int_field": 10, "closed_str_field": "abc", 
"from_closed_str_field": "abc", "open_int_field": 100, "open_str_field": "def" 
}, "add_from_open_int_field": { "id": 1, "closed_int_field": 10, 
"closed_str_field": "abc", "open_int_field": 100, "open_str_field": "def", 
"from_open_int_field": 100 }, "add_from_open_str_field": { "id": 1, 
"closed_int_field": 10, "closed_str_field": "abc", "open_int_field": 100, 
"open_str_field": "def", "from_open_str_field": "def" }, 
"add_from_closed_str_field_to_closed_int_field": { "id": 1, "closed_int_field": 
10, "closed_str_field": "abc", "open_int_field": 100, "open_str_field": "def" 
}, "add_from_closed_int_field_to_closed_str_field": { "id": 1, 
"closed_int_field": 10, "closed_str_field": "abc", "open_int_field": 100, 
"open_str_field": "def" }, "add_from_open_str_field_to_open_int_field": { "id": 
1, "closed_int_field": 10, "closed_str_field": "abc", "open_int_field": 100, 
"open_str_field": "def" }, "add_from_open_int_field_to_open_str_field": { "id": 
1, "closed_int_field": 10, "closed_str_field": "abc", "open_int_field": 100, 
"open_str_field": "def" }, "add_from_open_int_field_to_closed_int_field": { 
"id": 1, "closed_int_field": 10, "closed_str_field": "abc", "open_int_field": 
100, "open_str_field": "def" }, "add_from_open_str_field_to_closed_str_field": 
{ "id": 1, "closed_int_field": 10, "closed_str_field": "abc", "open_int_field": 
100, "open_str_field": "def" }, "add_from_closed_int_field_to_open_int_field": 
{ "id": 1, "closed_int_field": 10, "closed_str_field": "abc", "open_int_field": 
100, "open_str_field": "def" }, "add_from_closed_str_field_to_open_str_field": 
{ "id": 1, "closed_int_field": 10, "closed_str_field": "abc", "open_str_field": 
"def", "open_int_field": 100 } }
\ No newline at end of file
diff --git 
a/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/typecomputer/impl/AbstractRecordFunctionTypeComputer.java
 
b/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/typecomputer/impl/AbstractRecordFunctionTypeComputer.java
index 580cab4..371d69e 100644
--- 
a/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/typecomputer/impl/AbstractRecordFunctionTypeComputer.java
+++ 
b/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/typecomputer/impl/AbstractRecordFunctionTypeComputer.java
@@ -82,11 +82,11 @@
         isOutputNullable |= TypeHelper.canBeNull(type1);

         // Compute our type.
-        return computeTypeImpl(functionCallExpression, env, inputRecordType, 
isOutputMissable, isOutputNullable);
+        return computeTypeImpl(functionCallExpression, type0, env, 
inputRecordType, isOutputMissable, isOutputNullable);
     }

     protected abstract IAType computeTypeImpl(AbstractFunctionCallExpression 
functionCallExpression,
-            IVariableTypeEnvironment env, ARecordType inputRecordType, boolean 
isOutputMissable,
+            IAType arg0InRecType, IVariableTypeEnvironment env, ARecordType 
inputRecordType, boolean isOutputMissable,
             boolean isOutputNullable) throws AlgebricksException;

     protected static IAType wrapTypeWithUnknown(IAType originalType, boolean 
isMissable, boolean isNullable) {
diff --git 
a/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/typecomputer/impl/RecordAddTypeComputer.java
 
b/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/typecomputer/impl/RecordAddTypeComputer.java
index 4815340..fd874a5 100644
--- 
a/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/typecomputer/impl/RecordAddTypeComputer.java
+++ 
b/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/typecomputer/impl/RecordAddTypeComputer.java
@@ -40,17 +40,16 @@
     }

     @Override
-    public IAType computeTypeImpl(AbstractFunctionCallExpression 
functionCallExpression, IVariableTypeEnvironment env,
-            ARecordType inputRecordType, boolean isOutputMissable, boolean 
isOutputNullable)
-            throws AlgebricksException {
+    public IAType computeTypeImpl(AbstractFunctionCallExpression 
functionCallExpression, IAType arg0InRecType,
+            IVariableTypeEnvironment env, ARecordType inputRecordType, boolean 
isOutputMissable,
+            boolean isOutputNullable) throws AlgebricksException {
         // If our third argument is missing, then just return the type of our 
first argument.
         ILogicalExpression arg2 = 
functionCallExpression.getArguments().get(2).getValue();
         IAType type2 = (IAType) env.getType(arg2);
         IAType actualType2 = TypeComputeUtils.getActualType(type2);
         ATypeTag tag2 = actualType2.getTypeTag();
         if (tag2 == ATypeTag.MISSING) {
-            IAType type0 = (IAType) 
env.getType(functionCallExpression.getArguments().get(0).getValue());
-            return wrapTypeWithUnknown(type0, isOutputMissable, 
isOutputNullable);
+            return wrapTypeWithUnknown(arg0InRecType, isOutputMissable, 
isOutputNullable);
         }

         // We expect a constant for our second argument.
@@ -66,18 +65,23 @@
         // If our field is found, return the original record type. Otherwise, 
add our new field.
         ARecordType outputRecordType = inputRecordType;
         if 
(!Arrays.asList(inputRecordType.getFieldNames()).contains(newFieldName)) {
-            String[] fieldNames = new 
String[inputRecordType.getFieldNames().length + 1];
-            IAType[] fieldTypes = new 
IAType[inputRecordType.getFieldTypes().length + 1];
-            int currentCursorPosition = 0;
-            for (; currentCursorPosition < 
inputRecordType.getFieldNames().length; currentCursorPosition++) {
-                fieldNames[currentCursorPosition] = 
inputRecordType.getFieldNames()[currentCursorPosition];
-                fieldTypes[currentCursorPosition] = 
inputRecordType.getFieldTypes()[currentCursorPosition];
-            }
-            fieldNames[currentCursorPosition] = newFieldName;
-            fieldTypes[currentCursorPosition] = type2;
             String inputTypeName = inputRecordType.getTypeName();
             String outputTypeName = inputTypeName != null ? inputTypeName + 
"_add_" + newFieldName : null;
-            outputRecordType = new ARecordType(outputTypeName, fieldNames, 
fieldTypes, inputRecordType.isOpen());
+            if (actualType2.getTypeTag() == ATypeTag.ANY) {
+                outputRecordType = new ARecordType(outputTypeName, 
inputRecordType.getFieldNames(),
+                        inputRecordType.getFieldTypes(), true);
+            } else {
+                String[] fieldNames = new 
String[inputRecordType.getFieldNames().length + 1];
+                IAType[] fieldTypes = new 
IAType[inputRecordType.getFieldTypes().length + 1];
+                int currentCursorPosition = 0;
+                for (; currentCursorPosition < 
inputRecordType.getFieldNames().length; currentCursorPosition++) {
+                    fieldNames[currentCursorPosition] = 
inputRecordType.getFieldNames()[currentCursorPosition];
+                    fieldTypes[currentCursorPosition] = 
inputRecordType.getFieldTypes()[currentCursorPosition];
+                }
+                fieldNames[currentCursorPosition] = newFieldName;
+                fieldTypes[currentCursorPosition] = type2;
+                outputRecordType = new ARecordType(outputTypeName, fieldNames, 
fieldTypes, inputRecordType.isOpen());
+            }
         }
         return wrapTypeWithUnknown(outputRecordType, isOutputMissable, 
isOutputNullable);
     }
diff --git 
a/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/typecomputer/impl/RecordPutTypeComputer.java
 
b/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/typecomputer/impl/RecordPutTypeComputer.java
index a92907d..fe32770 100644
--- 
a/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/typecomputer/impl/RecordPutTypeComputer.java
+++ 
b/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/typecomputer/impl/RecordPutTypeComputer.java
@@ -41,9 +41,9 @@
     }

     @Override
-    public IAType computeTypeImpl(AbstractFunctionCallExpression 
functionCallExpression, IVariableTypeEnvironment env,
-            ARecordType inputRecordType, boolean isOutputMissable, boolean 
isOutputNullable)
-            throws AlgebricksException {
+    public IAType computeTypeImpl(AbstractFunctionCallExpression 
functionCallExpression, IAType arg0InRecType,
+            IVariableTypeEnvironment env, ARecordType inputRecordType, boolean 
isOutputMissable,
+            boolean isOutputNullable) throws AlgebricksException {
         // Extract the type of our third argument. If it is MISSING, then we 
are performing a field removal.
         ILogicalExpression arg2 = 
functionCallExpression.getArguments().get(2).getValue();
         IAType type2 = (IAType) env.getType(arg2);
@@ -62,6 +62,7 @@

         // Remove or replace our field name and type (dependent on the type of 
our third argument).
         boolean fieldFound = false;
+        boolean makeOpen = false;
         List<String> outputFieldNames = new ArrayList<>();
         List<IAType> outputFieldTypes = new ArrayList<>();
         for (int i = 0; i < inputRecordType.getFieldNames().length; i++) {
@@ -70,10 +71,15 @@
             if (!inputFieldName.equals(newFieldName)) {
                 outputFieldNames.add(inputFieldName);
                 outputFieldTypes.add(inputFieldType);
-
             } else {
                 fieldFound = true;
-                if (!isFieldRemoval) {
+                // we cannot add a field to the record type (schema) if it is 
ANY. fields that are part of the record
+                // type need to have a known type so that the proper 
(non-tagged) SerializerDeserializer can be used
+                // fields with ANY need to go to the open part of the record 
type, and we need to make the record type
+                // open if it is not already
+                if (actualType2.getTypeTag() == ATypeTag.ANY) {
+                    makeOpen = true;
+                } else if (!isFieldRemoval) {
                     // Replace our input field type.
                     outputFieldNames.add(inputFieldName);
                     outputFieldTypes.add(type2);
@@ -94,14 +100,18 @@
             // We have replaced our argument field.
             String outputTypeName = doesRecordHaveTypeName ? inputTypeName + 
"_replaced_" + newFieldName : null;
             outputRecordType = new ARecordType(outputTypeName, 
outputFieldNames.toArray(String[]::new),
-                    outputFieldTypes.toArray(IAType[]::new), 
inputRecordType.isOpen());
+                    outputFieldTypes.toArray(IAType[]::new), 
inputRecordType.isOpen() || makeOpen);
         } else if (!isFieldRemoval) { // && !wasFieldFound
-            // We need to insert our argument field.
-            outputFieldNames.add(newFieldName);
-            outputFieldTypes.add(type2);
+            if (actualType2.getTypeTag() != ATypeTag.ANY) {
+                // We need to insert our argument field.
+                outputFieldNames.add(newFieldName);
+                outputFieldTypes.add(type2);
+            } else {
+                makeOpen = true;
+            }
             String outputTypeName = doesRecordHaveTypeName ? inputTypeName + 
"_add_" + newFieldName : null;
             outputRecordType = new ARecordType(outputTypeName, 
outputFieldNames.toArray(String[]::new),
-                    outputFieldTypes.toArray(IAType[]::new), 
inputRecordType.isOpen());
+                    outputFieldTypes.toArray(IAType[]::new), 
inputRecordType.isOpen() || makeOpen);
         } else { // isFieldRemoval && !wasFieldFound
             // We have not found the field to remove.
             outputRecordType = inputRecordType;
diff --git 
a/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/typecomputer/impl/RecordRemoveTypeComputer.java
 
b/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/typecomputer/impl/RecordRemoveTypeComputer.java
index c447e65..f9a7208 100644
--- 
a/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/typecomputer/impl/RecordRemoveTypeComputer.java
+++ 
b/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/typecomputer/impl/RecordRemoveTypeComputer.java
@@ -38,8 +38,9 @@
     }

     @Override
-    public IAType computeTypeImpl(AbstractFunctionCallExpression 
functionCallExpression, IVariableTypeEnvironment env,
-            ARecordType inputRecordType, boolean isOutputMissable, boolean 
isOutputNullable) {
+    public IAType computeTypeImpl(AbstractFunctionCallExpression 
functionCallExpression, IAType arg0InRecType,
+            IVariableTypeEnvironment env, ARecordType inputRecordType, boolean 
isOutputMissable,
+            boolean isOutputNullable) {
         // We expect a CONSTANT expression. Otherwise, defer the removal to 
runtime.
         ILogicalExpression arg1 = 
functionCallExpression.getArguments().get(1).getValue();
         if (arg1.getExpressionTag() != LogicalExpressionTag.CONSTANT) {
diff --git 
a/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/typecomputer/impl/RecordRenameTypeComputer.java
 
b/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/typecomputer/impl/RecordRenameTypeComputer.java
index 4302082..7d80a27 100644
--- 
a/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/typecomputer/impl/RecordRenameTypeComputer.java
+++ 
b/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/typecomputer/impl/RecordRenameTypeComputer.java
@@ -45,9 +45,9 @@
     }

     @Override
-    public IAType computeTypeImpl(AbstractFunctionCallExpression 
functionCallExpression, IVariableTypeEnvironment env,
-            ARecordType inputRecordType, boolean isOutputMissable, boolean 
isOutputNullable)
-            throws AlgebricksException {
+    public IAType computeTypeImpl(AbstractFunctionCallExpression 
functionCallExpression, IAType arg0InRecType,
+            IVariableTypeEnvironment env, ARecordType inputRecordType, boolean 
isOutputMissable,
+            boolean isOutputNullable) throws AlgebricksException {
         // Our third argument should be of type "string".
         ILogicalExpression arg2 = 
functionCallExpression.getArguments().get(2).getValue();
         IAType type2 = (IAType) env.getType(arg2);

--
To view, visit https://asterix-gerrit.ics.uci.edu/c/asterixdb/+/21173?usp=email
To unsubscribe, or for help writing mail filters, visit 
https://asterix-gerrit.ics.uci.edu/settings?usp=email

Gerrit-MessageType: newchange
Gerrit-Project: asterixdb
Gerrit-Branch: lumina
Gerrit-Change-Id: Ieb3f6ed85c107ff849e34850a15505ea61fbb4eb
Gerrit-Change-Number: 21173
Gerrit-PatchSet: 1
Gerrit-Owner: Ali Alsuliman <[email protected]>

Reply via email to