asterixdb-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From mb...@apache.org
Subject [06/12] asterixdb git commit: [ASTERIXDB-2340][FUN] Implement object_length(), object_names()
Date Tue, 27 Mar 2018 23:48:29 GMT
[ASTERIXDB-2340][FUN] Implement object_length(), object_names()

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

Details:
- Implement object_length(), object_names() functions
- Consolidate type inferers for some object accessor functions

Change-Id: I1108466ffe4f6b002fa7dd25f76dd5e8d537b0be
Reviewed-on: https://asterix-gerrit.ics.uci.edu/2522
Tested-by: Jenkins <jenkins@fulliautomatix.ics.uci.edu>
Contrib: Jenkins <jenkins@fulliautomatix.ics.uci.edu>
Integration-Tests: Jenkins <jenkins@fulliautomatix.ics.uci.edu>
Reviewed-by: Till Westmann <tillw@apache.org>


Project: http://git-wip-us.apache.org/repos/asf/asterixdb/repo
Commit: http://git-wip-us.apache.org/repos/asf/asterixdb/commit/f7c7059c
Tree: http://git-wip-us.apache.org/repos/asf/asterixdb/tree/f7c7059c
Diff: http://git-wip-us.apache.org/repos/asf/asterixdb/diff/f7c7059c

Branch: refs/heads/master
Commit: f7c7059c7e3145129d32de474f7401c25df76d32
Parents: 8d28443
Author: Dmitry Lychagin <dmitry.lychagin@couchbase.com>
Authored: Mon Mar 26 15:57:48 2018 -0700
Committer: Michael Blow <mblow@apache.org>
Committed: Mon Mar 26 20:53:58 2018 -0700

----------------------------------------------------------------------
 .../queries_sqlpp/objects/ObjectsQueries.xml    |  10 ++
 .../object_length/object_length.1.ddl.sqlpp     |  49 +++++++
 .../object_length/object_length.2.update.sqlpp  |  29 ++++
 .../object_length/object_length.3.query.sqlpp   |  56 ++++++++
 .../object_names/object_names.1.ddl.sqlpp       |  49 +++++++
 .../object_names/object_names.2.update.sqlpp    |  29 ++++
 .../object_names/object_names.3.query.sqlpp     |  59 ++++++++
 .../objects/object_length/object_length.3.adm   |   1 +
 .../objects/object_names/object_names.3.adm     |   1 +
 .../src/main/markdown/builtins/8_record.md      |  54 ++++++++
 .../asterix/om/functions/BuiltinFunctions.java  |   6 +
 .../typecomputer/impl/AInt64TypeComputer.java   |  14 +-
 .../impl/OrderedListOfAStringTypeComputer.java  |  13 +-
 .../records/GetRecordFieldValueDescriptor.java  |   2 +-
 .../records/GetRecordFieldsDescriptor.java      |   2 +-
 .../records/RecordLengthDescriptor.java         | 122 +++++++++++++++++
 .../records/RecordNamesDescriptor.java          | 134 +++++++++++++++++++
 .../records/RecordPairsDescriptor.java          |   2 +-
 .../runtime/functions/FunctionCollection.java   |   4 +
 .../runtime/functions/FunctionTypeInferers.java |  66 ++++-----
 20 files changed, 653 insertions(+), 49 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/asterixdb/blob/f7c7059c/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/objects/ObjectsQueries.xml
----------------------------------------------------------------------
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 c5ff15b..507e276 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
@@ -108,6 +108,16 @@
     </compilation-unit>
   </test-case>
   <test-case FilePath="objects">
+    <compilation-unit name="object_length">
+      <output-dir compare="Text">object_length</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>
+  </test-case>
+  <test-case FilePath="objects">
     <compilation-unit name="object_pairs">
       <output-dir compare="Text">object_pairs</output-dir>
     </compilation-unit>

http://git-wip-us.apache.org/repos/asf/asterixdb/blob/f7c7059c/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/objects/object_length/object_length.1.ddl.sqlpp
----------------------------------------------------------------------
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/objects/object_length/object_length.1.ddl.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/objects/object_length/object_length.1.ddl.sqlpp
new file mode 100644
index 0000000..a50bf21
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/objects/object_length/object_length.1.ddl.sqlpp
@@ -0,0 +1,49 @@
+/*
+ * 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_length under different queries.
+ * Expected Res : Success
+ */
+
+drop  dataverse TinySocial if exists;
+create  dataverse TinySocial;
+
+use TinySocial;
+
+create type TinySocial.TwitterUserType as
+{
+  `screen-name` : string,
+  lang : string,
+  friends_count : bigint,
+  statuses_count : bigint
+};
+
+create type TinySocial.TweetMessageType as closed {
+  tweetid : string,
+  user : TwitterUserType,
+  `sender-location` : point?,
+  `send-time` : datetime,
+  `referred-topics` : {{string}},
+  `message-text` : string
+};
+
+create  dataset TwitterUsers(TwitterUserType) primary key `screen-name`;
+
+create  dataset TweetMessages(TweetMessageType) primary key tweetid;

http://git-wip-us.apache.org/repos/asf/asterixdb/blob/f7c7059c/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/objects/object_length/object_length.2.update.sqlpp
----------------------------------------------------------------------
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/objects/object_length/object_length.2.update.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/objects/object_length/object_length.2.update.sqlpp
new file mode 100644
index 0000000..1bd2260
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/objects/object_length/object_length.2.update.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  : Testing object_length under different queries.
+ * Expected Res : Success
+ */
+
+use TinySocial;
+
+load  dataset TwitterUsers using localfs ((`path`=`asterix_nc1://data/tinysocial/twu.adm`),(`format`=`adm`));
+
+load  dataset TweetMessages using localfs ((`path`=`asterix_nc1://data/tinysocial/twm.adm`),(`format`=`adm`));

http://git-wip-us.apache.org/repos/asf/asterixdb/blob/f7c7059c/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/objects/object_length/object_length.3.query.sqlpp
----------------------------------------------------------------------
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/objects/object_length/object_length.3.query.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/objects/object_length/object_length.3.query.sqlpp
new file mode 100644
index 0000000..67d88d9
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/objects/object_length/object_length.3.query.sqlpp
@@ -0,0 +1,56 @@
+/*
+ * 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_length under different queries.
+ * Expected Res : Success
+ */
+
+use TinySocial;
+
+{
+  "t1": [
+    object_length(missing) is missing,
+    object_length(null) is null,
+    object_length("{}") is null,
+    object_length(0) is null,
+    is_number(object_length({}))
+  ],
+
+  "t2": [ object_length({}), object_length({"a":1}), object_length({"a":1, "b": 2}) ],
+
+  "t3": (
+    select value object_length(o)
+    from (
+      select x, current_datetime() y from range(1, 3) x
+    ) o
+  ),
+
+  /* open type */
+  "t4": (
+    select distinct value object_length(t)
+    from TwitterUsers as t
+  ),
+
+  /* closed type */
+  "t5": (
+    select distinct value object_length(user)
+    from TweetMessages as t
+  )
+};

http://git-wip-us.apache.org/repos/asf/asterixdb/blob/f7c7059c/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/objects/object_names/object_names.1.ddl.sqlpp
----------------------------------------------------------------------
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/objects/object_names/object_names.1.ddl.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/objects/object_names/object_names.1.ddl.sqlpp
new file mode 100644
index 0000000..4f507b1
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/objects/object_names/object_names.1.ddl.sqlpp
@@ -0,0 +1,49 @@
+/*
+ * 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_names under different queries.
+ * Expected Res : Success
+ */
+
+drop  dataverse TinySocial if exists;
+create  dataverse TinySocial;
+
+use TinySocial;
+
+create type TinySocial.TwitterUserType as
+{
+  `screen-name` : string,
+  lang : string,
+  friends_count : bigint,
+  statuses_count : bigint
+};
+
+create type TinySocial.TweetMessageType as closed {
+  tweetid : string,
+  user : TwitterUserType,
+  `sender-location` : point?,
+  `send-time` : datetime,
+  `referred-topics` : {{string}},
+  `message-text` : string
+};
+
+create  dataset TwitterUsers(TwitterUserType) primary key `screen-name`;
+
+create  dataset TweetMessages(TweetMessageType) primary key tweetid;

http://git-wip-us.apache.org/repos/asf/asterixdb/blob/f7c7059c/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/objects/object_names/object_names.2.update.sqlpp
----------------------------------------------------------------------
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/objects/object_names/object_names.2.update.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/objects/object_names/object_names.2.update.sqlpp
new file mode 100644
index 0000000..cf03bed
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/objects/object_names/object_names.2.update.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  : Testing object_names under different queries.
+ * Expected Res : Success
+ */
+
+use TinySocial;
+
+load  dataset TwitterUsers using localfs ((`path`=`asterix_nc1://data/tinysocial/twu.adm`),(`format`=`adm`));
+
+load  dataset TweetMessages using localfs ((`path`=`asterix_nc1://data/tinysocial/twm.adm`),(`format`=`adm`));

http://git-wip-us.apache.org/repos/asf/asterixdb/blob/f7c7059c/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/objects/object_names/object_names.3.query.sqlpp
----------------------------------------------------------------------
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/objects/object_names/object_names.3.query.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/objects/object_names/object_names.3.query.sqlpp
new file mode 100644
index 0000000..ae20bb0
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/objects/object_names/object_names.3.query.sqlpp
@@ -0,0 +1,59 @@
+/*
+ * 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_names under different queries.
+ * Expected Res : Success
+ */
+
+use TinySocial;
+
+{
+  "t1": [
+    object_names(missing) is missing,
+    object_names(null) is null,
+    object_names("{}") is null,
+    object_names(0) is null,
+    is_array(object_names({}))
+  ],
+
+  "t2": [ object_names({}), object_names({"a":1}), object_names({"a":1, "b": 2}),
+          object_names({"a":1, "b": 2, "c": 3}) ],
+
+  "t3": (
+    select value object_names(o)
+    from (
+      select x, current_datetime() y from range(1, 3) x
+    ) o
+  ),
+
+  /* open type */
+  "t4": (
+    select distinct string_join((select value f from g order by f), ",") res
+    from TwitterUsers as t, object_names(t) f
+    group by t.`screen-name` group as g
+  ),
+
+  /* closed type */
+  "t5": (
+    select distinct string_join((select value f from g order by f), ",") res
+    from TweetMessages as t, object_names(t) f
+    group by t.tweetid group as g
+  )
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/asterixdb/blob/f7c7059c/asterixdb/asterix-app/src/test/resources/runtimets/results/objects/object_length/object_length.3.adm
----------------------------------------------------------------------
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/results/objects/object_length/object_length.3.adm b/asterixdb/asterix-app/src/test/resources/runtimets/results/objects/object_length/object_length.3.adm
new file mode 100644
index 0000000..f03b7d5
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/results/objects/object_length/object_length.3.adm
@@ -0,0 +1 @@
+{ "t1": [ true, true, true, true, true ], "t2": [ 0, 1, 2 ], "t3": [ 2, 2, 2 ], "t4": [ 6 ], "t5": [ 6 ] }
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/asterixdb/blob/f7c7059c/asterixdb/asterix-app/src/test/resources/runtimets/results/objects/object_names/object_names.3.adm
----------------------------------------------------------------------
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/results/objects/object_names/object_names.3.adm b/asterixdb/asterix-app/src/test/resources/runtimets/results/objects/object_names/object_names.3.adm
new file mode 100644
index 0000000..04441f8
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/results/objects/object_names/object_names.3.adm
@@ -0,0 +1 @@
+{ "t1": [ true, true, true, true, true ], "t2": [ [  ], [ "a" ], [ "a", "b" ], [ "a", "b", "c" ] ], "t3": [ [ "x", "y" ], [ "x", "y" ], [ "x", "y" ] ], "t4": [ { "res": "followers_count,friends_count,lang,name,screen-name,statuses_count" } ], "t5": [ { "res": "message-text,referred-topics,send-time,sender-location,tweetid,user" } ] }
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/asterixdb/blob/f7c7059c/asterixdb/asterix-doc/src/main/markdown/builtins/8_record.md
----------------------------------------------------------------------
diff --git a/asterixdb/asterix-doc/src/main/markdown/builtins/8_record.md b/asterixdb/asterix-doc/src/main/markdown/builtins/8_record.md
index d7ec35b..fefdb7b 100644
--- a/asterixdb/asterix-doc/src/main/markdown/builtins/8_record.md
+++ b/asterixdb/asterix-doc/src/main/markdown/builtins/8_record.md
@@ -233,3 +233,57 @@
           "id": 1
         }
 
+### object_length ###
+ * Syntax:
+
+        object_length(input_object)
+
+ * Returns number of top-level fields in the given object
+ * Arguments:
+    * `input_object` : an object value.
+ * Return Value:
+    * an integer that represents the number of top-level fields in the given object,
+    * `missing` if the argument is a `missing` value,
+    * `null` if the argument is a `null` value or any other non-object value
+
+ * Example:
+
+        object_length(
+                       {
+                         "id": 1,
+                         "project": "AsterixDB",
+                         "address": {"city": "Irvine", "state": "CA"},
+                       }
+                     );
+
+ * The expected result is:
+
+        3
+
+### object_names ###
+ * Syntax:
+
+        object_names(input_object)
+
+ * Returns names of top-level fields in the given object
+ * Arguments:
+    * `input_object` : an object value.
+ * Return Value:
+    * an array with top-level field names of the given object,
+    * `missing` if the argument is a `missing` value,
+    * `null` if the argument is a `null` value or any other non-object value
+
+ * Example:
+
+        object_names(
+                       {
+                         "id": 1,
+                         "project": "AsterixDB",
+                         "address": {"city": "Irvine", "state": "CA"},
+                       }
+                     );
+
+ * The expected result is:
+
+        [ "id", "project", "address" ]
+

http://git-wip-us.apache.org/repos/asf/asterixdb/blob/f7c7059c/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/functions/BuiltinFunctions.java
----------------------------------------------------------------------
diff --git a/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/functions/BuiltinFunctions.java b/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/functions/BuiltinFunctions.java
index 92617ee..6b86a26 100644
--- a/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/functions/BuiltinFunctions.java
+++ b/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/functions/BuiltinFunctions.java
@@ -205,6 +205,10 @@ public class BuiltinFunctions {
             new FunctionIdentifier(FunctionConstants.ASTERIX_NS, "get-object-fields", 1);
     public static final FunctionIdentifier GET_RECORD_FIELD_VALUE =
             new FunctionIdentifier(FunctionConstants.ASTERIX_NS, "get-object-field-value", 2);
+    public static final FunctionIdentifier RECORD_LENGTH =
+            new FunctionIdentifier(FunctionConstants.ASTERIX_NS, "object-length", 1);
+    public static final FunctionIdentifier RECORD_NAMES =
+            new FunctionIdentifier(FunctionConstants.ASTERIX_NS, "object-names", 1);
     public static final FunctionIdentifier RECORD_PAIRS =
             new FunctionIdentifier(FunctionConstants.ASTERIX_NS, "object-pairs", FunctionIdentifier.VARARGS);
 
@@ -1214,6 +1218,8 @@ public class BuiltinFunctions {
         addFunction(FIELD_ACCESS_BY_NAME, FieldAccessByNameResultType.INSTANCE, true);
         addFunction(GET_RECORD_FIELDS, OrderedListOfAnyTypeComputer.INSTANCE, true);
         addFunction(GET_RECORD_FIELD_VALUE, FieldAccessNestedResultType.INSTANCE, true);
+        addFunction(RECORD_LENGTH, AInt64TypeComputer.INSTANCE_NULLABLE, true);
+        addFunction(RECORD_NAMES, OrderedListOfAStringTypeComputer.INSTANCE_NULLABLE, true);
         addFunction(RECORD_PAIRS, RecordPairsTypeComputer.INSTANCE, true);
 
         // temporal type accessors

http://git-wip-us.apache.org/repos/asf/asterixdb/blob/f7c7059c/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/typecomputer/impl/AInt64TypeComputer.java
----------------------------------------------------------------------
diff --git a/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/typecomputer/impl/AInt64TypeComputer.java b/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/typecomputer/impl/AInt64TypeComputer.java
index 9909c3d..d495acf 100644
--- a/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/typecomputer/impl/AInt64TypeComputer.java
+++ b/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/typecomputer/impl/AInt64TypeComputer.java
@@ -19,6 +19,7 @@
 package org.apache.asterix.om.typecomputer.impl;
 
 import org.apache.asterix.om.typecomputer.base.AbstractResultTypeComputer;
+import org.apache.asterix.om.types.AUnionType;
 import org.apache.asterix.om.types.BuiltinType;
 import org.apache.asterix.om.types.IAType;
 import org.apache.hyracks.algebricks.common.exceptions.AlgebricksException;
@@ -26,14 +27,19 @@ import org.apache.hyracks.algebricks.core.algebra.base.ILogicalExpression;
 
 public class AInt64TypeComputer extends AbstractResultTypeComputer {
 
-    public static final AInt64TypeComputer INSTANCE = new AInt64TypeComputer();
+    public static final AInt64TypeComputer INSTANCE = new AInt64TypeComputer(false);
 
-    private AInt64TypeComputer() {
+    public static final AInt64TypeComputer INSTANCE_NULLABLE = new AInt64TypeComputer(true);
+
+    private final IAType type;
+
+    private AInt64TypeComputer(boolean nullable) {
+        IAType t = BuiltinType.AINT64;
+        type = nullable ? AUnionType.createNullableType(t) : t;
     }
 
     @Override
     protected IAType getResultType(ILogicalExpression expr, IAType... strippedInputTypes) throws AlgebricksException {
-        return BuiltinType.AINT64;
+        return type;
     }
-
 }

http://git-wip-us.apache.org/repos/asf/asterixdb/blob/f7c7059c/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/typecomputer/impl/OrderedListOfAStringTypeComputer.java
----------------------------------------------------------------------
diff --git a/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/typecomputer/impl/OrderedListOfAStringTypeComputer.java b/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/typecomputer/impl/OrderedListOfAStringTypeComputer.java
index bd35872..1d315e2 100644
--- a/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/typecomputer/impl/OrderedListOfAStringTypeComputer.java
+++ b/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/typecomputer/impl/OrderedListOfAStringTypeComputer.java
@@ -20,6 +20,7 @@ package org.apache.asterix.om.typecomputer.impl;
 
 import org.apache.asterix.om.typecomputer.base.AbstractResultTypeComputer;
 import org.apache.asterix.om.types.AOrderedListType;
+import org.apache.asterix.om.types.AUnionType;
 import org.apache.asterix.om.types.BuiltinType;
 import org.apache.asterix.om.types.IAType;
 import org.apache.hyracks.algebricks.common.exceptions.AlgebricksException;
@@ -27,13 +28,19 @@ import org.apache.hyracks.algebricks.core.algebra.base.ILogicalExpression;
 
 public class OrderedListOfAStringTypeComputer extends AbstractResultTypeComputer {
 
-    public static final OrderedListOfAStringTypeComputer INSTANCE = new OrderedListOfAStringTypeComputer();
+    public static final OrderedListOfAStringTypeComputer INSTANCE = new OrderedListOfAStringTypeComputer(false);
 
-    private OrderedListOfAStringTypeComputer() {
+    public static final OrderedListOfAStringTypeComputer INSTANCE_NULLABLE = new OrderedListOfAStringTypeComputer(true);
+
+    private final IAType type;
+
+    private OrderedListOfAStringTypeComputer(boolean nullable) {
+        IAType t = new AOrderedListType(BuiltinType.ASTRING, null);
+        type = nullable ? AUnionType.createNullableType(t) : t;
     }
 
     @Override
     protected IAType getResultType(ILogicalExpression expr, IAType... strippedInputTypes) throws AlgebricksException {
-        return new AOrderedListType(BuiltinType.ASTRING, null);
+        return type;
     }
 }

http://git-wip-us.apache.org/repos/asf/asterixdb/blob/f7c7059c/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/records/GetRecordFieldValueDescriptor.java
----------------------------------------------------------------------
diff --git a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/records/GetRecordFieldValueDescriptor.java b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/records/GetRecordFieldValueDescriptor.java
index 631dd70..4c07e2d 100644
--- a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/records/GetRecordFieldValueDescriptor.java
+++ b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/records/GetRecordFieldValueDescriptor.java
@@ -38,7 +38,7 @@ public class GetRecordFieldValueDescriptor extends AbstractScalarFunctionDynamic
 
         @Override
         public IFunctionTypeInferer createFunctionTypeInferer() {
-            return new FunctionTypeInferers.GetRecordFieldValueTypeInferer();
+            return FunctionTypeInferers.RecordAccessorTypeInferer.INSTANCE_STRICT;
         }
     };
 

http://git-wip-us.apache.org/repos/asf/asterixdb/blob/f7c7059c/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/records/GetRecordFieldsDescriptor.java
----------------------------------------------------------------------
diff --git a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/records/GetRecordFieldsDescriptor.java b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/records/GetRecordFieldsDescriptor.java
index 273e3ca..57e98d0 100644
--- a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/records/GetRecordFieldsDescriptor.java
+++ b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/records/GetRecordFieldsDescriptor.java
@@ -38,7 +38,7 @@ public class GetRecordFieldsDescriptor extends AbstractScalarFunctionDynamicDesc
 
         @Override
         public IFunctionTypeInferer createFunctionTypeInferer() {
-            return new FunctionTypeInferers.GetRecordFieldsTypeInferer();
+            return FunctionTypeInferers.RecordAccessorTypeInferer.INSTANCE_STRICT;
         }
     };
 

http://git-wip-us.apache.org/repos/asf/asterixdb/blob/f7c7059c/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/records/RecordLengthDescriptor.java
----------------------------------------------------------------------
diff --git a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/records/RecordLengthDescriptor.java b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/records/RecordLengthDescriptor.java
new file mode 100644
index 0000000..cda069d
--- /dev/null
+++ b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/records/RecordLengthDescriptor.java
@@ -0,0 +1,122 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.asterix.runtime.evaluators.functions.records;
+
+import java.io.DataOutput;
+
+import org.apache.asterix.formats.nontagged.SerializerDeserializerProvider;
+import org.apache.asterix.om.base.AInt64;
+import org.apache.asterix.om.base.AMutableInt64;
+import org.apache.asterix.om.functions.BuiltinFunctions;
+import org.apache.asterix.om.functions.IFunctionDescriptor;
+import org.apache.asterix.om.functions.IFunctionDescriptorFactory;
+import org.apache.asterix.om.functions.IFunctionTypeInferer;
+import org.apache.asterix.om.pointables.nonvisitor.ARecordPointable;
+import org.apache.asterix.om.types.ARecordType;
+import org.apache.asterix.om.types.ATypeTag;
+import org.apache.asterix.om.types.BuiltinType;
+import org.apache.asterix.runtime.evaluators.base.AbstractScalarFunctionDynamicDescriptor;
+import org.apache.asterix.runtime.evaluators.functions.PointableHelper;
+import org.apache.asterix.runtime.functions.FunctionTypeInferers;
+import org.apache.hyracks.algebricks.core.algebra.functions.FunctionIdentifier;
+import org.apache.hyracks.algebricks.runtime.base.IScalarEvaluator;
+import org.apache.hyracks.algebricks.runtime.base.IScalarEvaluatorFactory;
+import org.apache.hyracks.api.context.IHyracksTaskContext;
+import org.apache.hyracks.api.dataflow.value.ISerializerDeserializer;
+import org.apache.hyracks.api.exceptions.HyracksDataException;
+import org.apache.hyracks.data.std.api.IPointable;
+import org.apache.hyracks.data.std.primitive.VoidPointable;
+import org.apache.hyracks.data.std.util.ArrayBackedValueStorage;
+import org.apache.hyracks.dataflow.common.data.accessors.IFrameTupleReference;
+
+public class RecordLengthDescriptor extends AbstractScalarFunctionDynamicDescriptor {
+    public static final IFunctionDescriptorFactory FACTORY = new IFunctionDescriptorFactory() {
+        @Override
+        public IFunctionDescriptor createFunctionDescriptor() {
+            return new RecordLengthDescriptor();
+        }
+
+        @Override
+        public IFunctionTypeInferer createFunctionTypeInferer() {
+            return FunctionTypeInferers.RecordAccessorTypeInferer.INSTANCE_LAX;
+        }
+    };
+
+    private static final long serialVersionUID = 1L;
+    private ARecordType recType;
+
+    @Override
+    public void setImmutableStates(Object... states) {
+        this.recType = (ARecordType) states[0];
+    }
+
+    @Override
+    public IScalarEvaluatorFactory createEvaluatorFactory(final IScalarEvaluatorFactory[] args) {
+        return new IScalarEvaluatorFactory() {
+            private static final long serialVersionUID = 1L;
+
+            @Override
+            public IScalarEvaluator createScalarEvaluator(final IHyracksTaskContext ctx) throws HyracksDataException {
+                return new IScalarEvaluator() {
+
+                    private IScalarEvaluator eval0 = args[0].createScalarEvaluator(ctx);
+
+                    private final IPointable argPtr = new VoidPointable();
+                    private final ARecordPointable recordPointable =
+                            (ARecordPointable) ARecordPointable.FACTORY.createPointable();
+                    private final AMutableInt64 aInt64 = new AMutableInt64(0);
+                    @SuppressWarnings("unchecked")
+                    private final ISerializerDeserializer<AInt64> int64Serde =
+                            SerializerDeserializerProvider.INSTANCE.getSerializerDeserializer(BuiltinType.AINT64);
+                    private final ArrayBackedValueStorage resultStorage = new ArrayBackedValueStorage();
+                    private final DataOutput out = resultStorage.getDataOutput();
+
+                    @Override
+                    public void evaluate(IFrameTupleReference tuple, IPointable resultPointable)
+                            throws HyracksDataException {
+                        resultStorage.reset();
+                        eval0.evaluate(tuple, argPtr);
+
+                        byte[] data = argPtr.getByteArray();
+                        int offset = argPtr.getStartOffset();
+
+                        if (data[offset] != ATypeTag.SERIALIZED_RECORD_TYPE_TAG) {
+                            PointableHelper.setNull(resultPointable);
+                            return;
+                        }
+
+                        recordPointable.set(data, offset, argPtr.getLength());
+                        int n = recordPointable.getSchemeFieldCount(recType)
+                                + recordPointable.getOpenFieldCount(recType);
+
+                        aInt64.setValue(n);
+                        int64Serde.serialize(aInt64, out);
+                        resultPointable.set(resultStorage);
+                    }
+                };
+            }
+        };
+    }
+
+    @Override
+    public FunctionIdentifier getIdentifier() {
+        return BuiltinFunctions.RECORD_LENGTH;
+    }
+}

http://git-wip-us.apache.org/repos/asf/asterixdb/blob/f7c7059c/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/records/RecordNamesDescriptor.java
----------------------------------------------------------------------
diff --git a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/records/RecordNamesDescriptor.java b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/records/RecordNamesDescriptor.java
new file mode 100644
index 0000000..bb8e3e7
--- /dev/null
+++ b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/records/RecordNamesDescriptor.java
@@ -0,0 +1,134 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.asterix.runtime.evaluators.functions.records;
+
+import java.io.DataOutput;
+import java.io.IOException;
+
+import org.apache.asterix.builders.OrderedListBuilder;
+import org.apache.asterix.om.functions.BuiltinFunctions;
+import org.apache.asterix.om.functions.IFunctionDescriptor;
+import org.apache.asterix.om.functions.IFunctionDescriptorFactory;
+import org.apache.asterix.om.functions.IFunctionTypeInferer;
+import org.apache.asterix.om.pointables.nonvisitor.ARecordPointable;
+import org.apache.asterix.om.types.AOrderedListType;
+import org.apache.asterix.om.types.ARecordType;
+import org.apache.asterix.om.types.ATypeTag;
+import org.apache.asterix.runtime.evaluators.base.AbstractScalarFunctionDynamicDescriptor;
+import org.apache.asterix.runtime.evaluators.functions.PointableHelper;
+import org.apache.asterix.runtime.functions.FunctionTypeInferers;
+import org.apache.hyracks.algebricks.core.algebra.functions.FunctionIdentifier;
+import org.apache.hyracks.algebricks.runtime.base.IScalarEvaluator;
+import org.apache.hyracks.algebricks.runtime.base.IScalarEvaluatorFactory;
+import org.apache.hyracks.api.context.IHyracksTaskContext;
+import org.apache.hyracks.api.exceptions.HyracksDataException;
+import org.apache.hyracks.data.std.api.IPointable;
+import org.apache.hyracks.data.std.primitive.VoidPointable;
+import org.apache.hyracks.data.std.util.ArrayBackedValueStorage;
+import org.apache.hyracks.dataflow.common.data.accessors.IFrameTupleReference;
+
+public class RecordNamesDescriptor extends AbstractScalarFunctionDynamicDescriptor {
+    public static final IFunctionDescriptorFactory FACTORY = new IFunctionDescriptorFactory() {
+        @Override
+        public IFunctionDescriptor createFunctionDescriptor() {
+            return new RecordNamesDescriptor();
+        }
+
+        @Override
+        public IFunctionTypeInferer createFunctionTypeInferer() {
+            return FunctionTypeInferers.RecordAccessorTypeInferer.INSTANCE_LAX;
+        }
+    };
+
+    private static final long serialVersionUID = 1L;
+    private ARecordType recType;
+
+    @Override
+    public void setImmutableStates(Object... states) {
+        this.recType = (ARecordType) states[0];
+    }
+
+    @Override
+    public IScalarEvaluatorFactory createEvaluatorFactory(final IScalarEvaluatorFactory[] args) {
+        return new IScalarEvaluatorFactory() {
+            private static final long serialVersionUID = 1L;
+
+            @Override
+            public IScalarEvaluator createScalarEvaluator(final IHyracksTaskContext ctx) throws HyracksDataException {
+                return new IScalarEvaluator() {
+
+                    private IScalarEvaluator eval0 = args[0].createScalarEvaluator(ctx);
+                    private final IPointable argPtr = new VoidPointable();
+                    private final ARecordPointable recordPointable =
+                            (ARecordPointable) ARecordPointable.FACTORY.createPointable();
+                    private final OrderedListBuilder listBuilder = new OrderedListBuilder();
+                    private final ArrayBackedValueStorage itemStorage = new ArrayBackedValueStorage();
+                    private final DataOutput itemOut = itemStorage.getDataOutput();
+                    private final ArrayBackedValueStorage resultStorage = new ArrayBackedValueStorage();
+                    private final DataOutput resultOut = resultStorage.getDataOutput();
+
+                    @Override
+                    public void evaluate(IFrameTupleReference tuple, IPointable resultPointable)
+                            throws HyracksDataException {
+                        resultStorage.reset();
+                        eval0.evaluate(tuple, argPtr);
+
+                        byte[] data = argPtr.getByteArray();
+                        int offset = argPtr.getStartOffset();
+
+                        if (data[offset] != ATypeTag.SERIALIZED_RECORD_TYPE_TAG) {
+                            PointableHelper.setNull(resultPointable);
+                            return;
+                        }
+
+                        recordPointable.set(data, offset, argPtr.getLength());
+
+                        listBuilder.reset(AOrderedListType.FULL_OPEN_ORDEREDLIST_TYPE);
+
+                        try {
+                            for (int i = 0, n = recordPointable.getSchemeFieldCount(recType); i < n; i++) {
+                                itemStorage.reset();
+                                recordPointable.getClosedFieldName(recType, i, itemOut);
+                                listBuilder.addItem(itemStorage);
+                            }
+                            for (int i = 0, n = recordPointable.getOpenFieldCount(recType); i < n; i++) {
+                                itemStorage.reset();
+                                recordPointable.getOpenFieldName(recType, i, itemOut);
+                                listBuilder.addItem(itemStorage);
+                            }
+                        } catch (IOException e) {
+                            throw HyracksDataException.create(e);
+                        }
+
+                        listBuilder.write(resultOut, true);
+
+                        resultPointable.set(resultStorage);
+                    }
+                };
+            }
+        };
+    }
+
+    @Override
+    public FunctionIdentifier getIdentifier() {
+        return BuiltinFunctions.RECORD_NAMES;
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/asterixdb/blob/f7c7059c/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/records/RecordPairsDescriptor.java
----------------------------------------------------------------------
diff --git a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/records/RecordPairsDescriptor.java b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/records/RecordPairsDescriptor.java
index 2bf2530..96592e9 100644
--- a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/records/RecordPairsDescriptor.java
+++ b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/records/RecordPairsDescriptor.java
@@ -59,7 +59,7 @@ public class RecordPairsDescriptor extends AbstractScalarFunctionDynamicDescript
 
         @Override
         public IFunctionTypeInferer createFunctionTypeInferer() {
-            return new FunctionTypeInferers.RecordPairsTypeInferer();
+            return FunctionTypeInferers.RecordAccessorTypeInferer.INSTANCE_STRICT;
         }
     };
 

http://git-wip-us.apache.org/repos/asf/asterixdb/blob/f7c7059c/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/functions/FunctionCollection.java
----------------------------------------------------------------------
diff --git a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/functions/FunctionCollection.java b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/functions/FunctionCollection.java
index 487877b..6648ff2 100644
--- a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/functions/FunctionCollection.java
+++ b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/functions/FunctionCollection.java
@@ -263,7 +263,9 @@ import org.apache.asterix.runtime.evaluators.functions.records.GetRecordFieldsDe
 import org.apache.asterix.runtime.evaluators.functions.records.RecordAddFieldsDescriptor;
 import org.apache.asterix.runtime.evaluators.functions.records.RecordConcatDescriptor;
 import org.apache.asterix.runtime.evaluators.functions.records.RecordConcatStrictDescriptor;
+import org.apache.asterix.runtime.evaluators.functions.records.RecordLengthDescriptor;
 import org.apache.asterix.runtime.evaluators.functions.records.RecordMergeDescriptor;
+import org.apache.asterix.runtime.evaluators.functions.records.RecordNamesDescriptor;
 import org.apache.asterix.runtime.evaluators.functions.records.RecordPairsDescriptor;
 import org.apache.asterix.runtime.evaluators.functions.records.RecordRemoveFieldsDescriptor;
 import org.apache.asterix.runtime.evaluators.functions.temporal.AdjustDateTimeForTimeZoneDescriptor;
@@ -614,6 +616,8 @@ public final class FunctionCollection implements IFunctionCollection {
         fc.addGenerated(RecordMergeDescriptor.FACTORY);
         fc.addGenerated(RecordAddFieldsDescriptor.FACTORY);
         fc.addGenerated(RecordRemoveFieldsDescriptor.FACTORY);
+        fc.addGenerated(RecordLengthDescriptor.FACTORY);
+        fc.addGenerated(RecordNamesDescriptor.FACTORY);
 
         // Spatial and temporal type accessors
         fc.addGenerated(TemporalYearAccessor.FACTORY);

http://git-wip-us.apache.org/repos/asf/asterixdb/blob/f7c7059c/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/functions/FunctionTypeInferers.java
----------------------------------------------------------------------
diff --git a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/functions/FunctionTypeInferers.java b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/functions/FunctionTypeInferers.java
index 6261fb3..be041e5 100644
--- a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/functions/FunctionTypeInferers.java
+++ b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/functions/FunctionTypeInferers.java
@@ -149,36 +149,41 @@ public final class FunctionTypeInferers {
         }
     }
 
-    public static final class GetRecordFieldsTypeInferer implements IFunctionTypeInferer {
-        @Override
-        public void infer(ILogicalExpression expr, IFunctionDescriptor fd, IVariableTypeEnvironment context,
-                CompilerProperties compilerProps) throws AlgebricksException {
-            AbstractFunctionCallExpression fce = (AbstractFunctionCallExpression) expr;
-            IAType t = (IAType) context.getType(fce.getArguments().get(0).getValue());
-            ATypeTag typeTag = t.getTypeTag();
-            if (typeTag.equals(ATypeTag.OBJECT)) {
-                fd.setImmutableStates(t);
-            } else if (typeTag.equals(ATypeTag.ANY)) {
-                fd.setImmutableStates(RecordUtil.FULLY_OPEN_RECORD_TYPE);
-            } else {
-                throw new NotImplementedException("get-record-fields for data of type " + t);
-            }
+    public static final class RecordAccessorTypeInferer implements IFunctionTypeInferer {
+
+        public static final IFunctionTypeInferer INSTANCE_STRICT = new RecordAccessorTypeInferer(true);
+
+        public static final IFunctionTypeInferer INSTANCE_LAX = new RecordAccessorTypeInferer(false);
+
+        private final boolean strict;
+
+        private RecordAccessorTypeInferer(boolean strict) {
+            this.strict = strict;
         }
-    }
 
-    public static final class GetRecordFieldValueTypeInferer implements IFunctionTypeInferer {
         @Override
         public void infer(ILogicalExpression expr, IFunctionDescriptor fd, IVariableTypeEnvironment context,
                 CompilerProperties compilerProps) throws AlgebricksException {
             AbstractFunctionCallExpression fce = (AbstractFunctionCallExpression) expr;
             IAType t = (IAType) context.getType(fce.getArguments().get(0).getValue());
             ATypeTag typeTag = t.getTypeTag();
-            if (typeTag.equals(ATypeTag.OBJECT)) {
-                fd.setImmutableStates(t);
-            } else if (typeTag.equals(ATypeTag.ANY)) {
-                fd.setImmutableStates(RecordUtil.FULLY_OPEN_RECORD_TYPE);
-            } else {
-                throw new NotImplementedException("get-record-field-value for data of type " + t);
+            switch (typeTag) {
+                case OBJECT: {
+                    fd.setImmutableStates(t);
+                    break;
+                }
+                case ANY: {
+                    fd.setImmutableStates(RecordUtil.FULLY_OPEN_RECORD_TYPE);
+                    break;
+                }
+                default: {
+                    if (strict) {
+                        throw new NotImplementedException(fd.getIdentifier().getName() + " for data of type " + t);
+                    } else {
+                        fd.setImmutableStates(new Object[] { null });
+                    }
+                    break;
+                }
             }
         }
     }
@@ -243,23 +248,6 @@ public final class FunctionTypeInferers {
         }
     }
 
-    public static final class RecordPairsTypeInferer implements IFunctionTypeInferer {
-        @Override
-        public void infer(ILogicalExpression expr, IFunctionDescriptor fd, IVariableTypeEnvironment context,
-                CompilerProperties compilerProps) throws AlgebricksException {
-            AbstractFunctionCallExpression fce = (AbstractFunctionCallExpression) expr;
-            IAType t = (IAType) context.getType(fce.getArguments().get(0).getValue());
-            ATypeTag typeTag = t.getTypeTag();
-            if (typeTag.equals(ATypeTag.OBJECT)) {
-                fd.setImmutableStates(t);
-            } else if (typeTag.equals(ATypeTag.ANY)) {
-                fd.setImmutableStates(RecordUtil.FULLY_OPEN_RECORD_TYPE);
-            } else {
-                throw new NotImplementedException("record-fields with data of type " + t);
-            }
-        }
-    }
-
     public static final class RecordRemoveFieldsTypeInferer implements IFunctionTypeInferer {
         @Override
         public void infer(ILogicalExpression expr, IFunctionDescriptor fd, IVariableTypeEnvironment context,


Mime
View raw message