[NO ISSUE][FUN] Implement object-add(), object-put()
- user model changes: no
- storage format changes: no
- interface changes: no
Details:
- Implement object-add function that adds a new field
to a given object.
- Implement object-put function that adds, removes, or
updates an existing field in a given object.
- Add new functions to docs.
- Add test cases.
Change-Id: I0b0b33f4ea82752ced0b5fc8f54d4474711192fc
Reviewed-on: https://asterix-gerrit.ics.uci.edu/2713
Sonar-Qube: Jenkins <jenkins@fulliautomatix.ics.uci.edu>
Tested-by: Jenkins <jenkins@fulliautomatix.ics.uci.edu>
Contrib: Jenkins <jenkins@fulliautomatix.ics.uci.edu>
Reviewed-by: Murtadha Hubail <mhubail@apache.org>
Integration-Tests: Jenkins <jenkins@fulliautomatix.ics.uci.edu>
Reviewed-by: Dmitry Lychagin <dmitry.lychagin@couchbase.com>
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 184500e..42eeedd 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
@@ -140,6 +140,16 @@
<source-location>false</source-location>
</compilation-unit>
</test-case>
+ <test-case FilePath="objects">>
+ <compilation-unit name="object_add">
+ <output-dir compare="Text">object_add</output-dir>
+ </compilation-unit>
+ </test-case>
+ <test-case FilePath="objects">
+ <compilation-unit name="object_put">
+ <output-dir compare="Text">object_put</output-dir>
+ </compilation-unit>
+ </test-case>
<test-case FilePath="objects">
<compilation-unit name="object_pairs">
<output-dir compare="Text">object_pairs</output-dir>
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/objects/object_add/object_add.1.ddl.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/objects/object_add/object_add.1.ddl.sqlpp
new file mode 100644
index 0000000..0573cc7
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/objects/object_add/object_add.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_add 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;
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/objects/object_add/object_add.2.update.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/objects/object_add/object_add.2.update.sqlpp
new file mode 100644
index 0000000..2e1e348
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/objects/object_add/object_add.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_add 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`));
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/objects/object_add/object_add.3.query.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/objects/object_add/object_add.3.query.sqlpp
new file mode 100644
index 0000000..b3c90a2
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/objects/object_add/object_add.3.query.sqlpp
@@ -0,0 +1,58 @@
+/*
+ * 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_add under different queries.
+ * Expected Res : Success
+ */
+
+use TinySocial;
+
+{
+ "t1": [
+ object_add(missing, missing, "value") is missing,
+ object_add(null, missing, "value") is missing,
+ object_add(missing, null, missing) is missing,
+ object_add(null, null, null) is null,
+ object_add("a", null, null) is null,
+ object_add("non-object", "field", "value") is null,
+ object_add({"a":1}, 1, "value") is null
+ ],
+ "t2": object_add({"a":1}, "field", "value"),
+ "t3": object_add({"a":1}, "field", null),
+ "t4": object_add({"a":1}, "field", {"x":["y", "z"]}),
+ "t5": object_add({"a":1}, "a", 5),
+ "t6": object_add({"a":1}, "field", missing),
+
+ /* open type */
+ "t7": (
+ select value object_add(u, "field", "value")
+ from TwitterUsers as u
+ order by u.screen-name
+ limit 1
+ ),
+
+ /* closed type */
+ "t8": (
+ select value object_add(m, "field", {"a":1})
+ from TweetMessages as m
+ order by m.tweetid
+ limit 1
+ )
+};
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/objects/object_add/object_add.4.ddl.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/objects/object_add/object_add.4.ddl.sqlpp
new file mode 100644
index 0000000..58af156
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/objects/object_add/object_add.4.ddl.sqlpp
@@ -0,0 +1,25 @@
+/*
+ * 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_add under different queries.
+ * Expected Res : Success
+ */
+
+drop dataverse TinySocial;
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/objects/object_put/object_put.1.ddl.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/objects/object_put/object_put.1.ddl.sqlpp
new file mode 100644
index 0000000..6a7bed4
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/objects/object_put/object_put.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_put 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;
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/objects/object_put/object_put.2.update.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/objects/object_put/object_put.2.update.sqlpp
new file mode 100644
index 0000000..c40cedd
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/objects/object_put/object_put.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_put 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`));
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/objects/object_put/object_put.3.query.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/objects/object_put/object_put.3.query.sqlpp
new file mode 100644
index 0000000..3706fd1
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/objects/object_put/object_put.3.query.sqlpp
@@ -0,0 +1,58 @@
+/*
+ * 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 under different queries.
+ * Expected Res : Success
+ */
+
+use TinySocial;
+
+{
+ "t1": [
+ object_put(missing, missing, "value") is missing,
+ object_put(null, missing, "value") is missing,
+ object_put(missing, null, missing) is missing,
+ object_put(null, null, null) is null,
+ object_put("a", null, null) is null,
+ object_put("non-object", "field", "value") is null,
+ object_add({"a":1}, 1, "value") is null
+ ],
+ "t2": object_put({"a":1}, "field", "value"),
+ "t3": object_put({"a":1}, "field", null),
+ "t4": object_put({"a":1}, "field", {"x":["y", "z"]}),
+ "t5": object_put({"a":1}, "a", "replaced"),
+ "t6": object_put({"a":1, "removed":2}, "removed", missing),
+
+ /* open type */
+ "t7": (
+ select value object_put(u, "field", "value")
+ from TwitterUsers as u
+ order by u.screen-name
+ limit 1
+ ),
+
+ /* closed type */
+ "t8": (
+ select value object_put(m, "field", {"a":1})
+ from TweetMessages as m
+ order by m.tweetid
+ limit 1
+ )
+};
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/objects/object_put/object_put.4.ddl.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/objects/object_put/object_put.4.ddl.sqlpp
new file mode 100644
index 0000000..050057f
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/objects/object_put/object_put.4.ddl.sqlpp
@@ -0,0 +1,25 @@
+/*
+ * 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 under different queries.
+ * Expected Res : Success
+ */
+
+drop dataverse TinySocial;
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/results/objects/object_add/object_add.3.adm b/asterixdb/asterix-app/src/test/resources/runtimets/results/objects/object_add/object_add.3.adm
new file mode 100644
index 0000000..676edeb
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/results/objects/object_add/object_add.3.adm
@@ -0,0 +1 @@
+{ "t1": [ true, true, true, true, true, true, true ], "t2": { "a": 1, "field": "value" }, "t3": { "a": 1, "field": null }, "t4": { "a": 1, "field": { "x": [ "y", "z" ] } }, "t5": { "a": 1 }, "t6": { "a": 1 }, "t7": [ { "screen-name": "ChangEwing_573", "lang": "en", "friends_count": 182, "statuses_count": 394, "name": "Chang Ewing", "followers_count": 32136, "field": "value" } ], "t8": [ { "tweetid": "1", "user": { "screen-name": "NathanGiesen@211", "lang": "en", "friends_count": 39339, "statuses_count": 473, "name": "Nathan Giesen", "followers_count": 49416 }, "sender-location": point("47.44,80.65"), "send-time": datetime("2008-04-26T10:10:00.000Z"), "referred-topics": {{ "t-mobile", "customization" }}, "message-text": " love t-mobile its customization is good:)", "field": { "a": 1 } } ] }
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/results/objects/object_put/object_put.3.adm b/asterixdb/asterix-app/src/test/resources/runtimets/results/objects/object_put/object_put.3.adm
new file mode 100644
index 0000000..fc9a55a
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/results/objects/object_put/object_put.3.adm
@@ -0,0 +1 @@
+{ "t1": [ true, true, true, true, true, true, true ], "t2": { "a": 1, "field": "value" }, "t3": { "a": 1, "field": null }, "t4": { "a": 1, "field": { "x": [ "y", "z" ] } }, "t5": { "a": "replaced" }, "t6": { "a": 1 }, "t7": [ { "screen-name": "ChangEwing_573", "lang": "en", "friends_count": 182, "statuses_count": 394, "name": "Chang Ewing", "followers_count": 32136, "field": "value" } ], "t8": [ { "tweetid": "1", "user": { "screen-name": "NathanGiesen@211", "lang": "en", "friends_count": 39339, "statuses_count": 473, "name": "Nathan Giesen", "followers_count": 49416 }, "sender-location": point("47.44,80.65"), "send-time": datetime("2008-04-26T10:10:00.000Z"), "referred-topics": {{ "t-mobile", "customization" }}, "message-text": " love t-mobile its customization is good:)", "field": { "a": 1 } } ] }
\ No newline at end of file
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 df04b33..be2e008 100644
--- a/asterixdb/asterix-doc/src/main/markdown/builtins/8_record.md
+++ b/asterixdb/asterix-doc/src/main/markdown/builtins/8_record.md
@@ -423,3 +423,78 @@
"location": {"city": "Irvine", "state": "CA"}
}
+### object_add ###
+ * Syntax:
+
+ object_add(input_object, field_name, field_value)
+
+ * Returns a new object that has the same fields as `input_object` as well as the new field `field_name`.
+ * Arguments:
+ * `input_object` : an object value.
+ * `field_name` : a string representing a field name to be added.
+ * `field_value` : a value to be assigned to the new field `field_name`.
+ * Return Value:
+ * A new object that has the same fields as `input_object` as well as the new field `field_name`,
+ * `missing` if `input_object` or `field_name` is `missing`,
+ * `null` if `input_object` or `field_name` is `null`, or `input_object` is not an object, or `field_name` is not
+ a string,
+ * `input_object` if `field_name`already exists in `input_object` or `field_value` is missing.
+
+ * Example:
+
+ object_add(
+ {
+ "id": 1,
+ "project": "AsterixDB",
+ "address": {"city": "Irvine", "state": "CA"}
+ }
+ , "company"
+ , "Apache"
+ );
+
+ * The expected result is:
+
+ {
+ "id": 1,
+ "project": "AsterixDB",
+ "location": {"city": "Irvine", "state": "CA"},
+ "company": "Apache"
+ }
+
+### object_put ###
+ * Syntax:
+
+ object_put(input_object, field_name, field_value)
+
+ * Adds, modifies, or removes a field of an object.
+ * Arguments:
+ * `input_object` : an object value.
+ * `field_name` : a string representing a field name to be added.
+ * `field_value` : a value to be assigned to the new field `field_name`.
+ * Return Value:
+ * a new object that has the same fields as `input_object` as well as the new field `field_name`, or with updated
+ `field_name` value to `field_value` if `field_name` already exists in `input_object`, or with `field_name`removed
+ if `field_name` already exists in `input_object` and `field_value` is `missing`,
+ * `missing` if `input_object` or `field_name` is `missing`,
+ * `null` if `input_object` or `field_name` is `null`, or `input_object` is not an object, or `field_name` is not
+ not a string.
+
+ * Example:
+
+ object_put(
+ {
+ "id": 1,
+ "project": "AsterixDB",
+ "address": {"city": "Irvine", "state": "CA"}
+ }
+ , "project"
+ , "Apache AsterixDB"
+ );
+
+ * The expected result is:
+
+ {
+ "id": 1,
+ "project": "Apache AsterixDB",
+ "location": {"city": "Irvine", "state": "CA"}
+ }
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 f17bc47..c73680c 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
@@ -228,6 +228,10 @@
new FunctionIdentifier(FunctionConstants.ASTERIX_NS, "object-unwrap", 1);
public static final FunctionIdentifier RECORD_REPLACE =
new FunctionIdentifier(FunctionConstants.ASTERIX_NS, "object-replace", 3);
+ public static final FunctionIdentifier RECORD_ADD =
+ new FunctionIdentifier(FunctionConstants.ASTERIX_NS, "object-add", 3);
+ public static final FunctionIdentifier RECORD_PUT =
+ new FunctionIdentifier(FunctionConstants.ASTERIX_NS, "object-put", 3);
// numeric
public static final FunctionIdentifier NUMERIC_UNARY_MINUS =
@@ -1477,6 +1481,8 @@
addFunction(RECORD_RENAME, OpenARecordTypeComputer.INSTANCE, true);
addFunction(RECORD_UNWRAP, AnyTypeComputer.INSTANCE, true);
addFunction(RECORD_REPLACE, OpenARecordTypeComputer.INSTANCE, true);
+ addFunction(RECORD_ADD, OpenARecordTypeComputer.INSTANCE, true);
+ addFunction(RECORD_PUT, OpenARecordTypeComputer.INSTANCE, true);
// temporal type accessors
addFunction(ACCESSOR_TEMPORAL_YEAR, AInt64TypeComputer.INSTANCE, true);
diff --git a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/records/AbstractRecordAddPutEvaluator.java b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/records/AbstractRecordAddPutEvaluator.java
new file mode 100644
index 0000000..0fba990
--- /dev/null
+++ b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/records/AbstractRecordAddPutEvaluator.java
@@ -0,0 +1,114 @@
+/*
+ * 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.RecordBuilder;
+import org.apache.asterix.om.pointables.ARecordVisitablePointable;
+import org.apache.asterix.om.pointables.base.DefaultOpenFieldType;
+import org.apache.asterix.om.types.ATypeTag;
+import org.apache.asterix.om.types.BuiltinType;
+import org.apache.asterix.om.types.IAType;
+import org.apache.asterix.runtime.evaluators.functions.CastTypeEvaluator;
+import org.apache.asterix.runtime.evaluators.functions.PointableHelper;
+import org.apache.hyracks.algebricks.runtime.base.IScalarEvaluator;
+import org.apache.hyracks.api.dataflow.value.IBinaryComparator;
+import org.apache.hyracks.api.exceptions.HyracksDataException;
+import org.apache.hyracks.data.std.api.IPointable;
+import org.apache.hyracks.data.std.primitive.UTF8StringPointable;
+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;
+
+abstract class AbstractRecordAddPutEvaluator implements IScalarEvaluator {
+
+ private final CastTypeEvaluator inputRecordCaster;
+ private final CastTypeEvaluator argRecordCaster;
+ private final IScalarEvaluator eval0;
+ private final IScalarEvaluator eval1;
+ private final IScalarEvaluator eval2;
+ final ArrayBackedValueStorage resultStorage = new ArrayBackedValueStorage();
+ final DataOutput resultOutput = resultStorage.getDataOutput();
+ final IPointable inputRecordPointable = new VoidPointable();
+ final UTF8StringPointable newFieldNamePointable = new UTF8StringPointable();
+ final IPointable newFieldValuePointable = new VoidPointable();
+ final IBinaryComparator stringBinaryComparator = PointableHelper.createStringBinaryComparator();
+ final RecordBuilder outRecordBuilder = new RecordBuilder();
+ final ARecordVisitablePointable inputOpenRecordPointable;
+ boolean newFieldValueIsMissing = false;
+
+ AbstractRecordAddPutEvaluator(IScalarEvaluator eval0, IScalarEvaluator eval1, IScalarEvaluator eval2,
+ IAType[] argTypes) {
+ this.eval0 = eval0;
+ this.eval1 = eval1;
+ this.eval2 = eval2;
+ inputOpenRecordPointable = new ARecordVisitablePointable(DefaultOpenFieldType.NESTED_OPEN_RECORD_TYPE);
+ inputRecordCaster = new CastTypeEvaluator(BuiltinType.ANY, argTypes[0], eval0);
+ argRecordCaster = new CastTypeEvaluator(BuiltinType.ANY, argTypes[2], eval2);
+ }
+
+ @Override
+ public void evaluate(IFrameTupleReference tuple, IPointable result) throws HyracksDataException {
+ resultStorage.reset();
+ eval0.evaluate(tuple, inputRecordPointable);
+ eval1.evaluate(tuple, newFieldNamePointable);
+ eval2.evaluate(tuple, newFieldValuePointable);
+ if (containsMissing(inputRecordPointable, newFieldNamePointable)) {
+ writeTypeTag(ATypeTag.SERIALIZED_MISSING_TYPE_TAG);
+ result.set(resultStorage);
+ return;
+ }
+ final ATypeTag inputObjectType = PointableHelper.getTypeTag(inputRecordPointable);
+ final ATypeTag newFieldNameValueType = PointableHelper.getTypeTag(newFieldNamePointable);
+ if (inputObjectType != ATypeTag.OBJECT || newFieldNameValueType != ATypeTag.STRING) {
+ PointableHelper.setNull(result);
+ return;
+ }
+ inputRecordCaster.evaluate(tuple, inputRecordPointable);
+ final ATypeTag newFieldValueTag = PointableHelper.getTypeTag(newFieldValuePointable);
+ if (newFieldValueTag.isDerivedType()) {
+ argRecordCaster.evaluate(tuple, newFieldValuePointable);
+ }
+ newFieldValueIsMissing = newFieldValueTag == ATypeTag.MISSING;
+ buildOutputRecord();
+ result.set(resultStorage);
+ }
+
+ protected abstract void buildOutputRecord() throws HyracksDataException;
+
+ private boolean containsMissing(IPointable... pointables) {
+ for (int i = 0; i < pointables.length; i++) {
+ if (PointableHelper.getTypeTag(pointables[i]) == ATypeTag.MISSING) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ private void writeTypeTag(byte typeTag) throws HyracksDataException {
+ try {
+ resultOutput.writeByte(typeTag);
+ } catch (IOException e) {
+ throw HyracksDataException.create(e);
+ }
+ }
+}
\ No newline at end of file
diff --git a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/records/RecordAddDescriptor.java b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/records/RecordAddDescriptor.java
new file mode 100644
index 0000000..7788bc1
--- /dev/null
+++ b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/records/RecordAddDescriptor.java
@@ -0,0 +1,79 @@
+/*
+ * 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 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.types.IAType;
+import org.apache.asterix.runtime.evaluators.base.AbstractScalarFunctionDynamicDescriptor;
+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;
+
+public class RecordAddDescriptor extends AbstractScalarFunctionDynamicDescriptor {
+
+ public static final IFunctionDescriptorFactory FACTORY = new IFunctionDescriptorFactory() {
+ @Override
+ public IFunctionDescriptor createFunctionDescriptor() {
+ return new RecordAddDescriptor();
+ }
+
+ @Override
+ public IFunctionTypeInferer createFunctionTypeInferer() {
+ return FunctionTypeInferers.SET_ARGUMENTS_TYPE;
+ }
+ };
+
+ private static final long serialVersionUID = 1L;
+ private IAType[] argTypes;
+
+ @Override
+ public void setImmutableStates(Object... states) {
+ argTypes = new IAType[states.length];
+ for (int i = 0; i < states.length; i++) {
+ argTypes[i] = (IAType) states[i];
+ }
+ }
+
+ @Override
+ public IScalarEvaluatorFactory createEvaluatorFactory(final IScalarEvaluatorFactory[] args) {
+ return new IScalarEvaluatorFactory() {
+ private static final long serialVersionUID = 1L;
+
+ @Override
+ public IScalarEvaluator createScalarEvaluator(IHyracksTaskContext ctx) throws HyracksDataException {
+ final IScalarEvaluator[] argEvals = new IScalarEvaluator[args.length];
+ for (int i = 0; i < args.length; i++) {
+ argEvals[i] = args[i].createScalarEvaluator(ctx);
+ }
+ return new RecordAddEvaluator(argEvals[0], argEvals[1], argEvals[2], argTypes);
+ }
+ };
+ }
+
+ @Override
+ public FunctionIdentifier getIdentifier() {
+ return BuiltinFunctions.RECORD_ADD;
+ }
+}
diff --git a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/records/RecordAddEvaluator.java b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/records/RecordAddEvaluator.java
new file mode 100644
index 0000000..bdadfb6
--- /dev/null
+++ b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/records/RecordAddEvaluator.java
@@ -0,0 +1,58 @@
+/*
+ * 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.util.List;
+
+import org.apache.asterix.om.pointables.base.DefaultOpenFieldType;
+import org.apache.asterix.om.pointables.base.IVisitablePointable;
+import org.apache.asterix.om.types.IAType;
+import org.apache.asterix.runtime.evaluators.functions.PointableHelper;
+import org.apache.hyracks.algebricks.runtime.base.IScalarEvaluator;
+import org.apache.hyracks.api.exceptions.HyracksDataException;
+
+class RecordAddEvaluator extends AbstractRecordAddPutEvaluator {
+
+ RecordAddEvaluator(IScalarEvaluator eval0, IScalarEvaluator eval1, IScalarEvaluator eval2, IAType[] argTypes) {
+ super(eval0, eval1, eval2, argTypes);
+ }
+
+ @Override
+ protected void buildOutputRecord() throws HyracksDataException {
+ resultStorage.reset();
+ outRecordBuilder.reset(DefaultOpenFieldType.NESTED_OPEN_RECORD_TYPE);
+ outRecordBuilder.init();
+ inputOpenRecordPointable.set(inputRecordPointable);
+ final List<IVisitablePointable> fieldNames = inputOpenRecordPointable.getFieldNames();
+ final List<IVisitablePointable> fieldValues = inputOpenRecordPointable.getFieldValues();
+ boolean newFieldFound = false;
+ for (int i = 0, fieldCount = fieldNames.size(); i < fieldCount; i++) {
+ final IVisitablePointable fieldName = fieldNames.get(i);
+ if (PointableHelper.isEqual(fieldName, newFieldNamePointable, stringBinaryComparator)) {
+ newFieldFound = true;
+ }
+ outRecordBuilder.addField(fieldName, fieldValues.get(i));
+ }
+ if (!newFieldValueIsMissing && !newFieldFound) {
+ outRecordBuilder.addField(newFieldNamePointable, newFieldValuePointable);
+ }
+ outRecordBuilder.write(resultOutput, true);
+ }
+}
\ No newline at end of file
diff --git a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/records/RecordPutDescriptor.java b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/records/RecordPutDescriptor.java
new file mode 100644
index 0000000..a312795
--- /dev/null
+++ b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/records/RecordPutDescriptor.java
@@ -0,0 +1,79 @@
+/*
+ * 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 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.types.IAType;
+import org.apache.asterix.runtime.evaluators.base.AbstractScalarFunctionDynamicDescriptor;
+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;
+
+public class RecordPutDescriptor extends AbstractScalarFunctionDynamicDescriptor {
+
+ public static final IFunctionDescriptorFactory FACTORY = new IFunctionDescriptorFactory() {
+ @Override
+ public IFunctionDescriptor createFunctionDescriptor() {
+ return new RecordPutDescriptor();
+ }
+
+ @Override
+ public IFunctionTypeInferer createFunctionTypeInferer() {
+ return FunctionTypeInferers.SET_ARGUMENTS_TYPE;
+ }
+ };
+
+ private static final long serialVersionUID = 1L;
+ private IAType[] argTypes;
+
+ @Override
+ public void setImmutableStates(Object... states) {
+ argTypes = new IAType[states.length];
+ for (int i = 0; i < states.length; i++) {
+ argTypes[i] = (IAType) states[i];
+ }
+ }
+
+ @Override
+ public IScalarEvaluatorFactory createEvaluatorFactory(final IScalarEvaluatorFactory[] args) {
+ return new IScalarEvaluatorFactory() {
+ private static final long serialVersionUID = 1L;
+
+ @Override
+ public IScalarEvaluator createScalarEvaluator(IHyracksTaskContext ctx) throws HyracksDataException {
+ final IScalarEvaluator[] argEvals = new IScalarEvaluator[args.length];
+ for (int i = 0; i < args.length; i++) {
+ argEvals[i] = args[i].createScalarEvaluator(ctx);
+ }
+ return new RecordPutEvaluator(argEvals[0], argEvals[1], argEvals[2], argTypes);
+ }
+ };
+ }
+
+ @Override
+ public FunctionIdentifier getIdentifier() {
+ return BuiltinFunctions.RECORD_PUT;
+ }
+}
diff --git a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/records/RecordPutEvaluator.java b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/records/RecordPutEvaluator.java
new file mode 100644
index 0000000..83ee0c4
--- /dev/null
+++ b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/records/RecordPutEvaluator.java
@@ -0,0 +1,66 @@
+/*
+ * 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.util.List;
+
+import org.apache.asterix.om.pointables.base.DefaultOpenFieldType;
+import org.apache.asterix.om.pointables.base.IVisitablePointable;
+import org.apache.asterix.om.types.IAType;
+import org.apache.asterix.runtime.evaluators.functions.PointableHelper;
+import org.apache.hyracks.algebricks.runtime.base.IScalarEvaluator;
+import org.apache.hyracks.api.exceptions.HyracksDataException;
+
+class RecordPutEvaluator extends AbstractRecordAddPutEvaluator {
+
+ RecordPutEvaluator(IScalarEvaluator eval0, IScalarEvaluator eval1, IScalarEvaluator eval2, IAType[] argTypes) {
+ super(eval0, eval1, eval2, argTypes);
+ }
+
+ @Override
+ protected void buildOutputRecord() throws HyracksDataException {
+ resultStorage.reset();
+ outRecordBuilder.reset(DefaultOpenFieldType.NESTED_OPEN_RECORD_TYPE);
+ outRecordBuilder.init();
+ inputOpenRecordPointable.set(inputRecordPointable);
+ final List<IVisitablePointable> fieldNames = inputOpenRecordPointable.getFieldNames();
+ final List<IVisitablePointable> fieldValues = inputOpenRecordPointable.getFieldValues();
+ boolean newFieldFound = false;
+ for (int i = 0, fieldCount = fieldNames.size(); i < fieldCount; i++) {
+ final IVisitablePointable fieldName = fieldNames.get(i);
+ if (!PointableHelper.isEqual(fieldName, newFieldNamePointable, stringBinaryComparator)) {
+ outRecordBuilder.addField(fieldName, fieldValues.get(i));
+ } else {
+ newFieldFound = true;
+ if (!newFieldValueIsMissing) {
+ putNewField();
+ }
+ }
+ }
+ if (!newFieldFound) {
+ putNewField();
+ }
+ outRecordBuilder.write(resultOutput, true);
+ }
+
+ private void putNewField() throws HyracksDataException {
+ outRecordBuilder.addField(newFieldNamePointable, newFieldValuePointable);
+ }
+}
\ No newline at end of file
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 7663f19..f69ee7c 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
@@ -186,11 +186,10 @@
import org.apache.asterix.runtime.evaluators.functions.NumericATanDescriptor;
import org.apache.asterix.runtime.evaluators.functions.NumericAbsDescriptor;
import org.apache.asterix.runtime.evaluators.functions.NumericAddDescriptor;
-import org.apache.asterix.runtime.evaluators.functions.NumericDivDescriptor;
-import org.apache.asterix.runtime.evaluators.functions.NumericPowerDescriptor;
import org.apache.asterix.runtime.evaluators.functions.NumericCeilingDescriptor;
import org.apache.asterix.runtime.evaluators.functions.NumericCosDescriptor;
import org.apache.asterix.runtime.evaluators.functions.NumericDegreesDescriptor;
+import org.apache.asterix.runtime.evaluators.functions.NumericDivDescriptor;
import org.apache.asterix.runtime.evaluators.functions.NumericDivideDescriptor;
import org.apache.asterix.runtime.evaluators.functions.NumericExpDescriptor;
import org.apache.asterix.runtime.evaluators.functions.NumericFloorDescriptor;
@@ -198,6 +197,7 @@
import org.apache.asterix.runtime.evaluators.functions.NumericLogDescriptor;
import org.apache.asterix.runtime.evaluators.functions.NumericModuloDescriptor;
import org.apache.asterix.runtime.evaluators.functions.NumericMultiplyDescriptor;
+import org.apache.asterix.runtime.evaluators.functions.NumericPowerDescriptor;
import org.apache.asterix.runtime.evaluators.functions.NumericRadiansDescriptor;
import org.apache.asterix.runtime.evaluators.functions.NumericRoundDescriptor;
import org.apache.asterix.runtime.evaluators.functions.NumericRoundHalfToEven2Descriptor;
@@ -275,6 +275,7 @@
import org.apache.asterix.runtime.evaluators.functions.records.FieldAccessNestedDescriptor;
import org.apache.asterix.runtime.evaluators.functions.records.GetRecordFieldValueDescriptor;
import org.apache.asterix.runtime.evaluators.functions.records.GetRecordFieldsDescriptor;
+import org.apache.asterix.runtime.evaluators.functions.records.RecordAddDescriptor;
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;
@@ -282,6 +283,7 @@
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.RecordPutDescriptor;
import org.apache.asterix.runtime.evaluators.functions.records.RecordRemoveDescriptor;
import org.apache.asterix.runtime.evaluators.functions.records.RecordRemoveFieldsDescriptor;
import org.apache.asterix.runtime.evaluators.functions.records.RecordRenameDescriptor;
@@ -656,6 +658,8 @@
fc.addGenerated(RecordRenameDescriptor.FACTORY);
fc.addGenerated(RecordUnwrapDescriptor.FACTORY);
fc.add(RecordReplaceDescriptor.FACTORY);
+ fc.add(RecordAddDescriptor.FACTORY);
+ fc.add(RecordPutDescriptor.FACTORY);
// Spatial and temporal type accessors
fc.addGenerated(TemporalYearAccessor.FACTORY);