Ali Alsuliman has uploaded a new change for review.
https://asterix-gerrit.ics.uci.edu/2751
Change subject: [NO ISSUE][FUN] Implement array functions 1
......................................................................
[NO ISSUE][FUN] Implement array functions 1
- user model changes: no
- storage format changes: no
- interface changes: no
details:
This is part of implementing array functions. This patch
includes array_insert(), array_append(), array_prepend()
array_put() and array_remove(). It includes re-organization
of those functions.
Change-Id: I7d9cb80325138daf99fb039793446d109481c94b
---
M
asterixdb/asterix-app/src/test/java/org/apache/asterix/runtime/ExceptionIT.java
M
asterixdb/asterix-app/src/test/java/org/apache/asterix/runtime/NullMissingTest.java
M
asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/array_fun/array_append/array_append.3.query.sqlpp
A
asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/array_fun/array_insert/array_insert.1.ddl.sqlpp
A
asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/array_fun/array_insert/array_insert.2.update.sqlpp
A
asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/array_fun/array_insert/array_insert.3.query.sqlpp
A
asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/array_fun/array_insert/array_insert.4.ddl.sqlpp
A
asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/array_fun/array_prepend/array_prepend.1.ddl.sqlpp
A
asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/array_fun/array_prepend/array_prepend.2.update.sqlpp
A
asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/array_fun/array_prepend/array_prepend.3.query.sqlpp
A
asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/array_fun/array_prepend/array_prepend.4.ddl.sqlpp
A
asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/array_fun/array_put/array_put.1.ddl.sqlpp
A
asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/array_fun/array_put/array_put.2.update.sqlpp
A
asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/array_fun/array_put/array_put.3.query.sqlpp
A
asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/array_fun/array_put/array_put.4.query.sqlpp
A
asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/array_fun/array_put/array_put.5.query.sqlpp
A
asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/array_fun/array_put/array_put.6.ddl.sqlpp
A
asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/array_fun/array_remove/array_remove.1.ddl.sqlpp
A
asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/array_fun/array_remove/array_remove.2.update.sqlpp
A
asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/array_fun/array_remove/array_remove.3.query.sqlpp
A
asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/array_fun/array_remove/array_remove.4.query.sqlpp
A
asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/array_fun/array_remove/array_remove.5.query.sqlpp
A
asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/array_fun/array_remove/array_remove.6.ddl.sqlpp
M
asterixdb/asterix-app/src/test/resources/runtimets/results/array_fun/array_append/array_append.3.adm
A
asterixdb/asterix-app/src/test/resources/runtimets/results/array_fun/array_insert/array_insert.3.adm
A
asterixdb/asterix-app/src/test/resources/runtimets/results/array_fun/array_prepend/array_prepend.3.adm
A
asterixdb/asterix-app/src/test/resources/runtimets/results/array_fun/array_put/array_put.3.adm
A
asterixdb/asterix-app/src/test/resources/runtimets/results/array_fun/array_remove/array_remove.3.adm
M asterixdb/asterix-app/src/test/resources/runtimets/testsuite_sqlpp.xml
M
asterixdb/asterix-om/src/main/java/org/apache/asterix/om/functions/BuiltinFunctions.java
R
asterixdb/asterix-om/src/main/java/org/apache/asterix/om/typecomputer/impl/AListFirstTypeComputer.java
A
asterixdb/asterix-om/src/main/java/org/apache/asterix/om/typecomputer/impl/AListOrNullTypeComputer.java
D
asterixdb/asterix-om/src/main/java/org/apache/asterix/om/typecomputer/impl/ArrayAppendTypeComputer.java
M
asterixdb/asterix-om/src/test/java/org/apache/asterix/om/typecomputer/TypeComputerTest.java
A
asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/AbstractArrayAddRemoveEval.java
M
asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/ArrayAppendDescriptor.java
A
asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/ArrayInsertDescriptor.java
A
asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/ArrayPrependDescriptor.java
A
asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/ArrayPutDescriptor.java
A
asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/ArrayRemoveDescriptor.java
M
asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/CastTypeEvaluator.java
M
asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/PointableHelper.java
M
asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/functions/FunctionCollection.java
43 files changed, 1,462 insertions(+), 174 deletions(-)
git pull ssh://asterix-gerrit.ics.uci.edu:29418/asterixdb
refs/changes/51/2751/1
diff --git
a/asterixdb/asterix-app/src/test/java/org/apache/asterix/runtime/ExceptionIT.java
b/asterixdb/asterix-app/src/test/java/org/apache/asterix/runtime/ExceptionIT.java
index e764c32..fc59cee 100644
---
a/asterixdb/asterix-app/src/test/java/org/apache/asterix/runtime/ExceptionIT.java
+++
b/asterixdb/asterix-app/src/test/java/org/apache/asterix/runtime/ExceptionIT.java
@@ -52,7 +52,8 @@
// record and cast functions, which requires type settings.
String[] splits = className.split("\\.");
if (className.contains("Gen") && !className.contains("record") &&
!className.contains("Cast")
- && !splits[splits.length - 1].startsWith("Array")) {
+ && !splits[splits.length - 1].startsWith("Array")
+ && !splits[splits.length - 1].startsWith("AbstractArray"))
{
testFunction(func);
++testedFunctions;
}
diff --git
a/asterixdb/asterix-app/src/test/java/org/apache/asterix/runtime/NullMissingTest.java
b/asterixdb/asterix-app/src/test/java/org/apache/asterix/runtime/NullMissingTest.java
index f6f617e..15f7119 100644
---
a/asterixdb/asterix-app/src/test/java/org/apache/asterix/runtime/NullMissingTest.java
+++
b/asterixdb/asterix-app/src/test/java/org/apache/asterix/runtime/NullMissingTest.java
@@ -41,7 +41,8 @@
public class NullMissingTest {
- private static final String arrayAppend = "ArrayAppendDescriptor";
+ private static final String arrayName = "Array";
+ private static final String abstractArray = "AbstractArray";
@Test
public void test() throws Exception {
@@ -55,7 +56,8 @@
// record and cast functions, which requires type settings (we
test them in runtime tests).
splits = className.split("\\.");
if (className.contains("Gen") && !className.contains("record") &&
!className.contains("Cast")
- && !splits[splits.length - 1].startsWith(arrayAppend)) {
+ && !splits[splits.length - 1].startsWith(arrayName)
+ && !splits[splits.length - 1].startsWith(abstractArray)) {
testFunction(func);
++testedFunctions;
}
diff --git
a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/array_fun/array_append/array_append.3.query.sqlpp
b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/array_fun/array_append/array_append.3.query.sqlpp
index 8488e22..b675140 100755
---
a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/array_fun/array_append/array_append.3.query.sqlpp
+++
b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/array_fun/array_append/array_append.3.query.sqlpp
@@ -22,10 +22,11 @@
{
"t1": (select array_append(t.`referred-topics`, "sth", 5) from TweetMessages
t order by t.tweetid),
"t2": (select array_append([3, "John"], (select value v.compType from d1
v))),
- "t3": (select array_append([3], 7, null, missing)),
- "t4": (select array_append("non_array", 5)),
- "t5": (select array_append("non_array", 5, missing)),
- "t6": (select array_append([], 5, 10, 12.0, "sth")),
- "t7": (select array_append(missing, 3, 9)),
- "t8": (select array_append(null, 3, 9))
+ "t3": (array_append([3], 7, null, missing)), // missing
+ "t4": (array_append("non_array", 5)), // null
+ "t5": (array_append("non_array", 5, missing)), // missing
+ "t6": (array_append([], 5, 10, 12.0, "sth")), // OK
+ "t7": (array_append(missing, 3, 9)), // missing
+ "t8": (array_append(null, 3, 9)), // null
+ "t9": (array_append([3], 3, [9], null, "sth")) // OK to add nulls
};
\ No newline at end of file
diff --git
a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/array_fun/array_insert/array_insert.1.ddl.sqlpp
b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/array_fun/array_insert/array_insert.1.ddl.sqlpp
new file mode 100755
index 0000000..257c4dd
--- /dev/null
+++
b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/array_fun/array_insert/array_insert.1.ddl.sqlpp
@@ -0,0 +1,46 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+drop dataverse TinySocial if exists;
+create dataverse TinySocial;
+
+use TinySocial;
+
+
+create type TinySocial.TwitterUserType as
+{
+ `screen-name` : string,
+ lang : string,
+ friends_count : bigint,
+ statuses_count : bigint,
+ name : string,
+ followers_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 TweetMessages(TweetMessageType) primary key tweetid hints
(`CARDINALITY`=`100`);
\ No newline at end of file
diff --git
a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/array_fun/array_insert/array_insert.2.update.sqlpp
b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/array_fun/array_insert/array_insert.2.update.sqlpp
new file mode 100755
index 0000000..4a0e7ed
--- /dev/null
+++
b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/array_fun/array_insert/array_insert.2.update.sqlpp
@@ -0,0 +1,22 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+use TinySocial;
+
+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/array_fun/array_insert/array_insert.3.query.sqlpp
b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/array_fun/array_insert/array_insert.3.query.sqlpp
new file mode 100755
index 0000000..137c9fa
--- /dev/null
+++
b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/array_fun/array_insert/array_insert.3.query.sqlpp
@@ -0,0 +1,43 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+use TinySocial;
+
+{
+ "t1": (array_insert([1,2,3], 0, "a", "b")), // OK
+ "t2": (array_insert([1,2,3], 3, "a", "b")), // OK
+ "t3": (array_insert([1,1,2,4], 3, "a", "b")), // OK
+ "t4": (array_insert([1,1,2,4], 3, 7, "a", 7, "one more")), // OK
+ "t5": (array_insert([1,2,3], 4, "a")), // null, out of bound
+ "t6": (array_insert([1,2,3], -1, "a", "b")), // OK
+ "t7": (array_insert([1,2,3], -4, "a", "b")), // null, out of bound
+ "t8": (array_insert("non_array", 5, "val")), // null
+ "t9": (array_insert("non_array", 5, missing)), // missing
+ "t10": (array_insert([], 5, 10, 12.0, "sth")), // null, out of bound
+ "t11": (array_insert([], 0, 10, 12.0, "sth")), // OK
+ "t12": (array_insert([6], "a", 9)), // null, position non-numeric
+ "t13": (array_insert([6], 1.0, 9)), // OK
+ "t14": (array_insert([6], 1.5, 9)), // OK
+ "t15": (array_insert(null, 3, 9)), // null
+ "t16": (array_insert(missing, 3, 9)), // missing
+ "t17": (array_insert([6], 1, null, 9, null)), // OK to insert nulls
+ "t18": (array_insert([6], null, 5, 9, null)), // null
+ "t19": (array_insert([6], 3, null, missing, 9, null)), // missing
+ "t20": (select array_insert(t.`referred-topics`, 0, 5) from TweetMessages t
order by t.tweetid)
+};
\ No newline at end of file
diff --git
a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/array_fun/array_insert/array_insert.4.ddl.sqlpp
b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/array_fun/array_insert/array_insert.4.ddl.sqlpp
new file mode 100755
index 0000000..3f8c8ec
--- /dev/null
+++
b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/array_fun/array_insert/array_insert.4.ddl.sqlpp
@@ -0,0 +1,20 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+drop dataverse TinySocial;
\ No newline at end of file
diff --git
a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/array_fun/array_prepend/array_prepend.1.ddl.sqlpp
b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/array_fun/array_prepend/array_prepend.1.ddl.sqlpp
new file mode 100755
index 0000000..1c55a9a
--- /dev/null
+++
b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/array_fun/array_prepend/array_prepend.1.ddl.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.
+ */
+
+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,
+ name : string,
+ followers_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 type t1 AS {
+
+};
+
+create type t2 AS {
+id: int,
+compType: t1
+};
+
+create dataset TweetMessages(TweetMessageType) primary key tweetid hints
(`CARDINALITY`=`100`);
+create dataset d1(t2) primary key id;
\ No newline at end of file
diff --git
a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/array_fun/array_prepend/array_prepend.2.update.sqlpp
b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/array_fun/array_prepend/array_prepend.2.update.sqlpp
new file mode 100755
index 0000000..2767210
--- /dev/null
+++
b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/array_fun/array_prepend/array_prepend.2.update.sqlpp
@@ -0,0 +1,27 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+use TinySocial;
+
+load dataset TweetMessages using localfs
((`path`=`asterix_nc1://data/tinysocial/twm.adm`),(`format`=`adm`));
+
+insert into d1([
+{"id":1, "compType":{"sth":33}},
+{"id":2, "compType":{"sth":44}}
+]);
\ No newline at end of file
diff --git
a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/array_fun/array_prepend/array_prepend.3.query.sqlpp
b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/array_fun/array_prepend/array_prepend.3.query.sqlpp
new file mode 100755
index 0000000..90bb6a4
--- /dev/null
+++
b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/array_fun/array_prepend/array_prepend.3.query.sqlpp
@@ -0,0 +1,32 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+use TinySocial;
+
+{
+ "t1": (select array_prepend("sth", 5, t.`referred-topics`) from
TweetMessages t order by t.tweetid),
+ "t2": (select array_prepend((select value v.compType from d1 v), [3,
"John"])),
+ "t3": (array_prepend(7, null, missing, [3])), // missing
+ "t4": (array_prepend(5, "non_array")), // null
+ "t5": (array_prepend(5, missing, "non_array")), // missing
+ "t6": (array_prepend(5, 10, 12.0, "sth",[77, "val"])), // OK
+ "t7": (array_prepend(5, 10, null, "sth",[77, "val"])), // OK to insert
nulls
+ "t8": (array_prepend(3, 9, missing)), // missing
+ "t9": (array_prepend(3, 9, null)) // null
+};
\ No newline at end of file
diff --git
a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/array_fun/array_prepend/array_prepend.4.ddl.sqlpp
b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/array_fun/array_prepend/array_prepend.4.ddl.sqlpp
new file mode 100755
index 0000000..3f8c8ec
--- /dev/null
+++
b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/array_fun/array_prepend/array_prepend.4.ddl.sqlpp
@@ -0,0 +1,20 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+drop dataverse TinySocial;
\ No newline at end of file
diff --git
a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/array_fun/array_put/array_put.1.ddl.sqlpp
b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/array_fun/array_put/array_put.1.ddl.sqlpp
new file mode 100755
index 0000000..1c55a9a
--- /dev/null
+++
b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/array_fun/array_put/array_put.1.ddl.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.
+ */
+
+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,
+ name : string,
+ followers_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 type t1 AS {
+
+};
+
+create type t2 AS {
+id: int,
+compType: t1
+};
+
+create dataset TweetMessages(TweetMessageType) primary key tweetid hints
(`CARDINALITY`=`100`);
+create dataset d1(t2) primary key id;
\ No newline at end of file
diff --git
a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/array_fun/array_put/array_put.2.update.sqlpp
b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/array_fun/array_put/array_put.2.update.sqlpp
new file mode 100755
index 0000000..2767210
--- /dev/null
+++
b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/array_fun/array_put/array_put.2.update.sqlpp
@@ -0,0 +1,27 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+use TinySocial;
+
+load dataset TweetMessages using localfs
((`path`=`asterix_nc1://data/tinysocial/twm.adm`),(`format`=`adm`));
+
+insert into d1([
+{"id":1, "compType":{"sth":33}},
+{"id":2, "compType":{"sth":44}}
+]);
\ No newline at end of file
diff --git
a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/array_fun/array_put/array_put.3.query.sqlpp
b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/array_fun/array_put/array_put.3.query.sqlpp
new file mode 100755
index 0000000..2e37af2
--- /dev/null
+++
b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/array_fun/array_put/array_put.3.query.sqlpp
@@ -0,0 +1,33 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+use TinySocial;
+
+{
+ "t1": (select array_put(t.`referred-topics`, "t-mobile", 5) from
TweetMessages t order by t.tweetid),
+ "t2": (array_put([3], 7, null, missing)), // missing
+ "t3": (array_put("non_array", 5)), // null
+ "t4": (array_put("non_array", 5, missing)), // missing
+ "t5": (array_put([], 5, 10, 12.0, "sth")), // OK
+ "t6": (array_put(missing, 3, 9)), // missing
+ "t7": (array_put(null, 3, 9)), // null
+ "t8": (array_put([3,2,"sth"], 3, 9, 9, 3, "sth")), // OK
+ "t9": (array_put([3,2,"sth"], 1, 5)), // OK
+ "t10": (array_put([3,2,"sth"], null, 5)) // null
+};
\ No newline at end of file
diff --git
a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/array_fun/array_put/array_put.4.query.sqlpp
b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/array_fun/array_put/array_put.4.query.sqlpp
new file mode 100755
index 0000000..a462600
--- /dev/null
+++
b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/array_fun/array_put/array_put.4.query.sqlpp
@@ -0,0 +1,22 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+use TinySocial;
+
+select array_put([3, "John"], (select value v.compType from d1 v));
\ No newline at end of file
diff --git
a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/array_fun/array_put/array_put.5.query.sqlpp
b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/array_fun/array_put/array_put.5.query.sqlpp
new file mode 100755
index 0000000..0d27117
--- /dev/null
+++
b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/array_fun/array_put/array_put.5.query.sqlpp
@@ -0,0 +1,22 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+use TinySocial;
+
+select array_put([3], 3, [9], 4, "sth");
\ No newline at end of file
diff --git
a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/array_fun/array_put/array_put.6.ddl.sqlpp
b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/array_fun/array_put/array_put.6.ddl.sqlpp
new file mode 100755
index 0000000..3f8c8ec
--- /dev/null
+++
b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/array_fun/array_put/array_put.6.ddl.sqlpp
@@ -0,0 +1,20 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+drop dataverse TinySocial;
\ No newline at end of file
diff --git
a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/array_fun/array_remove/array_remove.1.ddl.sqlpp
b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/array_fun/array_remove/array_remove.1.ddl.sqlpp
new file mode 100755
index 0000000..1c55a9a
--- /dev/null
+++
b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/array_fun/array_remove/array_remove.1.ddl.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.
+ */
+
+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,
+ name : string,
+ followers_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 type t1 AS {
+
+};
+
+create type t2 AS {
+id: int,
+compType: t1
+};
+
+create dataset TweetMessages(TweetMessageType) primary key tweetid hints
(`CARDINALITY`=`100`);
+create dataset d1(t2) primary key id;
\ No newline at end of file
diff --git
a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/array_fun/array_remove/array_remove.2.update.sqlpp
b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/array_fun/array_remove/array_remove.2.update.sqlpp
new file mode 100755
index 0000000..2767210
--- /dev/null
+++
b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/array_fun/array_remove/array_remove.2.update.sqlpp
@@ -0,0 +1,27 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+use TinySocial;
+
+load dataset TweetMessages using localfs
((`path`=`asterix_nc1://data/tinysocial/twm.adm`),(`format`=`adm`));
+
+insert into d1([
+{"id":1, "compType":{"sth":33}},
+{"id":2, "compType":{"sth":44}}
+]);
\ No newline at end of file
diff --git
a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/array_fun/array_remove/array_remove.3.query.sqlpp
b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/array_fun/array_remove/array_remove.3.query.sqlpp
new file mode 100755
index 0000000..f726e7c
--- /dev/null
+++
b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/array_fun/array_remove/array_remove.3.query.sqlpp
@@ -0,0 +1,32 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+use TinySocial;
+
+{
+ "t1": (select array_remove(t.`referred-topics`, "t-mobile") from
TweetMessages t order by t.tweetid),
+ "t2": (array_remove([3], 7, null, missing)), // missing
+ "t3": (array_remove("non_array", 5)), // null
+ "t4": (array_remove("non_array", 5, missing)), // missing
+ "t5": (array_remove([], 5, 10, 12.0, "sth")), // OK
+ "t6": (array_remove(missing, 3, 9)), // missing
+ "t7": (array_remove(null, 3, 9)), // null
+ "t8": (array_remove([3,2,"sth"], 3, 9, 9, 3, "sth")), // OK
+ "t9": (array_remove([3,2,"sth"], 1, null)) // null
+};
\ No newline at end of file
diff --git
a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/array_fun/array_remove/array_remove.4.query.sqlpp
b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/array_fun/array_remove/array_remove.4.query.sqlpp
new file mode 100755
index 0000000..2dfa514
--- /dev/null
+++
b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/array_fun/array_remove/array_remove.4.query.sqlpp
@@ -0,0 +1,22 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+use TinySocial;
+
+select array_remove([3, "John"], (select value v.compType from d1 v));
\ No newline at end of file
diff --git
a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/array_fun/array_remove/array_remove.5.query.sqlpp
b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/array_fun/array_remove/array_remove.5.query.sqlpp
new file mode 100755
index 0000000..bfa878f
--- /dev/null
+++
b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/array_fun/array_remove/array_remove.5.query.sqlpp
@@ -0,0 +1,22 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+use TinySocial;
+
+select array_remove([3], 3, [9], 4, "sth");
\ No newline at end of file
diff --git
a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/array_fun/array_remove/array_remove.6.ddl.sqlpp
b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/array_fun/array_remove/array_remove.6.ddl.sqlpp
new file mode 100755
index 0000000..3f8c8ec
--- /dev/null
+++
b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/array_fun/array_remove/array_remove.6.ddl.sqlpp
@@ -0,0 +1,20 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+drop dataverse TinySocial;
\ No newline at end of file
diff --git
a/asterixdb/asterix-app/src/test/resources/runtimets/results/array_fun/array_append/array_append.3.adm
b/asterixdb/asterix-app/src/test/resources/runtimets/results/array_fun/array_append/array_append.3.adm
index c435e4e..adfdfa4 100644
---
a/asterixdb/asterix-app/src/test/resources/runtimets/results/array_fun/array_append/array_append.3.adm
+++
b/asterixdb/asterix-app/src/test/resources/runtimets/results/array_fun/array_append/array_append.3.adm
@@ -1 +1 @@
-{ "t1": [ { "$1": {{ "t-mobile", "customization", "sth", 5 }} }, { "$1": {{
"verizon", "voice-clarity", "sth", 5 }} }, { "$1": {{ "iphone", "platform",
"sth", 5 }} }, { "$1": {{ "samsung", "voice-command", "sth", 5 }} }, { "$1": {{
"verizon", "shortcut-menu", "sth", 5 }} }, { "$1": {{ "motorola", "speed",
"sth", 5 }} }, { "$1": {{ "sprint", "voice-command", "sth", 5 }} }, { "$1": {{
"motorola", "speed", "sth", 5 }} }, { "$1": {{ "iphone", "voice-clarity",
"sth", 5 }} }, { "$1": {{ "samsung", "platform", "sth", 5 }} }, { "$1": {{
"t-mobile", "shortcut-menu", "sth", 5 }} }, { "$1": {{ "verizon",
"voicemail-service", "sth", 5 }} } ], "t2": [ { "$2": [ 3, "John", [ { "sth":
33 }, { "sth": 44 } ] ] } ], "t3": [ { } ], "t4": [ { "$4": null } ], "t5": [
{ } ], "t6": [ { "$6": [ 5, 10, 12.0, "sth" ] } ], "t7": [ { } ], "t8": [ {
"$8": null } ] }
+{ "t1": [ { "$1": {{ "t-mobile", "customization", "sth", 5 }} }, { "$1": {{
"verizon", "voice-clarity", "sth", 5 }} }, { "$1": {{ "iphone", "platform",
"sth", 5 }} }, { "$1": {{ "samsung", "voice-command", "sth", 5 }} }, { "$1": {{
"verizon", "shortcut-menu", "sth", 5 }} }, { "$1": {{ "motorola", "speed",
"sth", 5 }} }, { "$1": {{ "sprint", "voice-command", "sth", 5 }} }, { "$1": {{
"motorola", "speed", "sth", 5 }} }, { "$1": {{ "iphone", "voice-clarity",
"sth", 5 }} }, { "$1": {{ "samsung", "platform", "sth", 5 }} }, { "$1": {{
"t-mobile", "shortcut-menu", "sth", 5 }} }, { "$1": {{ "verizon",
"voicemail-service", "sth", 5 }} } ], "t2": [ { "$2": [ 3, "John", [ { "sth":
33 }, { "sth": 44 } ] ] } ], "t4": null, "t6": [ 5, 10, 12.0, "sth" ], "t8":
null, "t9": [ 3, 3, [ 9 ], null, "sth" ] }
diff --git
a/asterixdb/asterix-app/src/test/resources/runtimets/results/array_fun/array_insert/array_insert.3.adm
b/asterixdb/asterix-app/src/test/resources/runtimets/results/array_fun/array_insert/array_insert.3.adm
new file mode 100644
index 0000000..86bc114
--- /dev/null
+++
b/asterixdb/asterix-app/src/test/resources/runtimets/results/array_fun/array_insert/array_insert.3.adm
@@ -0,0 +1 @@
+{ "t1": [ "a", "b", 1, 2, 3 ], "t2": [ 1, 2, 3, "a", "b" ], "t3": [ 1, 1, 2,
"a", "b", 4 ], "t4": [ 1, 1, 2, 7, "a", 7, "one more", 4 ], "t5": null, "t6": [
1, 2, "a", "b", 3 ], "t7": null, "t8": null, "t10": null, "t11": [ 10, 12.0,
"sth" ], "t12": null, "t13": [ 6, 9 ], "t14": [ 6, 9 ], "t15": null, "t17": [
6, null, 9, null ], "t18": null, "t20": [ { "$1": {{ 5, "t-mobile",
"customization" }} }, { "$1": {{ 5, "verizon", "voice-clarity" }} }, { "$1": {{
5, "iphone", "platform" }} }, { "$1": {{ 5, "samsung", "voice-command" }} }, {
"$1": {{ 5, "verizon", "shortcut-menu" }} }, { "$1": {{ 5, "motorola", "speed"
}} }, { "$1": {{ 5, "sprint", "voice-command" }} }, { "$1": {{ 5, "motorola",
"speed" }} }, { "$1": {{ 5, "iphone", "voice-clarity" }} }, { "$1": {{ 5,
"samsung", "platform" }} }, { "$1": {{ 5, "t-mobile", "shortcut-menu" }} }, {
"$1": {{ 5, "verizon", "voicemail-service" }} } ] }
diff --git
a/asterixdb/asterix-app/src/test/resources/runtimets/results/array_fun/array_prepend/array_prepend.3.adm
b/asterixdb/asterix-app/src/test/resources/runtimets/results/array_fun/array_prepend/array_prepend.3.adm
new file mode 100644
index 0000000..47f109c
--- /dev/null
+++
b/asterixdb/asterix-app/src/test/resources/runtimets/results/array_fun/array_prepend/array_prepend.3.adm
@@ -0,0 +1 @@
+{ "t1": [ { "$1": {{ "sth", 5, "t-mobile", "customization" }} }, { "$1": {{
"sth", 5, "verizon", "voice-clarity" }} }, { "$1": {{ "sth", 5, "iphone",
"platform" }} }, { "$1": {{ "sth", 5, "samsung", "voice-command" }} }, { "$1":
{{ "sth", 5, "verizon", "shortcut-menu" }} }, { "$1": {{ "sth", 5, "motorola",
"speed" }} }, { "$1": {{ "sth", 5, "sprint", "voice-command" }} }, { "$1": {{
"sth", 5, "motorola", "speed" }} }, { "$1": {{ "sth", 5, "iphone",
"voice-clarity" }} }, { "$1": {{ "sth", 5, "samsung", "platform" }} }, { "$1":
{{ "sth", 5, "t-mobile", "shortcut-menu" }} }, { "$1": {{ "sth", 5, "verizon",
"voicemail-service" }} } ], "t2": [ { "$2": [ [ { "sth": 33 }, { "sth": 44 } ],
3, "John" ] } ], "t4": null, "t6": [ 5, 10, 12.0, "sth", 77, "val" ], "t7": [
5, 10, null, "sth", 77, "val" ], "t9": null }
diff --git
a/asterixdb/asterix-app/src/test/resources/runtimets/results/array_fun/array_put/array_put.3.adm
b/asterixdb/asterix-app/src/test/resources/runtimets/results/array_fun/array_put/array_put.3.adm
new file mode 100644
index 0000000..e76b132
--- /dev/null
+++
b/asterixdb/asterix-app/src/test/resources/runtimets/results/array_fun/array_put/array_put.3.adm
@@ -0,0 +1 @@
+{ "t1": [ { "$1": {{ "t-mobile", "customization", 5 }} }, { "$1": {{
"verizon", "voice-clarity", "t-mobile", 5 }} }, { "$1": {{ "iphone",
"platform", "t-mobile", 5 }} }, { "$1": {{ "samsung", "voice-command",
"t-mobile", 5 }} }, { "$1": {{ "verizon", "shortcut-menu", "t-mobile", 5 }} },
{ "$1": {{ "motorola", "speed", "t-mobile", 5 }} }, { "$1": {{ "sprint",
"voice-command", "t-mobile", 5 }} }, { "$1": {{ "motorola", "speed",
"t-mobile", 5 }} }, { "$1": {{ "iphone", "voice-clarity", "t-mobile", 5 }} }, {
"$1": {{ "samsung", "platform", "t-mobile", 5 }} }, { "$1": {{ "t-mobile",
"shortcut-menu", 5 }} }, { "$1": {{ "verizon", "voicemail-service", "t-mobile",
5 }} } ], "t3": null, "t5": [ 5, 10, 12.0, "sth" ], "t7": null, "t8": [ 3, 2,
"sth", 9, 9 ], "t9": [ 3, 2, "sth", 1, 5 ], "t10": null }
diff --git
a/asterixdb/asterix-app/src/test/resources/runtimets/results/array_fun/array_remove/array_remove.3.adm
b/asterixdb/asterix-app/src/test/resources/runtimets/results/array_fun/array_remove/array_remove.3.adm
new file mode 100644
index 0000000..f579aa3
--- /dev/null
+++
b/asterixdb/asterix-app/src/test/resources/runtimets/results/array_fun/array_remove/array_remove.3.adm
@@ -0,0 +1 @@
+{ "t1": [ { "$1": {{ "customization" }} }, { "$1": {{ "verizon",
"voice-clarity" }} }, { "$1": {{ "iphone", "platform" }} }, { "$1": {{
"samsung", "voice-command" }} }, { "$1": {{ "verizon", "shortcut-menu" }} }, {
"$1": {{ "motorola", "speed" }} }, { "$1": {{ "sprint", "voice-command" }} }, {
"$1": {{ "motorola", "speed" }} }, { "$1": {{ "iphone", "voice-clarity" }} }, {
"$1": {{ "samsung", "platform" }} }, { "$1": {{ "shortcut-menu" }} }, { "$1":
{{ "verizon", "voicemail-service" }} } ], "t3": null, "t5": [ ], "t7": null,
"t8": [ 2 ], "t9": null }
diff --git
a/asterixdb/asterix-app/src/test/resources/runtimets/testsuite_sqlpp.xml
b/asterixdb/asterix-app/src/test/resources/runtimets/testsuite_sqlpp.xml
index 87bf893..2050746 100644
--- a/asterixdb/asterix-app/src/test/resources/runtimets/testsuite_sqlpp.xml
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/testsuite_sqlpp.xml
@@ -984,6 +984,11 @@
</test-group>
<test-group name="array_fun">
<test-case FilePath="array_fun">
+ <compilation-unit name="array_prepend">
+ <output-dir compare="Text">array_prepend</output-dir>
+ </compilation-unit>
+ </test-case>
+ <test-case FilePath="array_fun">
<compilation-unit name="array_append">
<output-dir compare="Text">array_append</output-dir>
</compilation-unit>
@@ -1012,6 +1017,25 @@
<expected-error>HYR0115: Cannot compare non-primitive values (in line
22, at column 8)</expected-error>
</compilation-unit>
</test-case>
+ <test-case FilePath="array_fun">
+ <compilation-unit name="array_insert">
+ <output-dir compare="Text">array_insert</output-dir>
+ </compilation-unit>
+ </test-case>
+ <test-case FilePath="array_fun">
+ <compilation-unit name="array_put">
+ <output-dir compare="Text">array_put</output-dir>
+ <expected-error>HYR0115: Cannot compare non-primitive values (in line
22, at column 8)</expected-error>
+ <expected-error>HYR0115: Cannot compare non-primitive values (in line
22, at column 8)</expected-error>
+ </compilation-unit>
+ </test-case>
+ <test-case FilePath="array_fun">
+ <compilation-unit name="array_remove">
+ <output-dir compare="Text">array_remove</output-dir>
+ <expected-error>HYR0115: Cannot compare non-primitive values (in line
22, at column 8)</expected-error>
+ <expected-error>HYR0115: Cannot compare non-primitive values (in line
22, at column 8)</expected-error>
+ </compilation-unit>
+ </test-case>
</test-group>
<test-group name="boolean">
<test-case FilePath="boolean">
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 da45e29..2b1c165 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
@@ -43,7 +43,8 @@
import org.apache.asterix.om.typecomputer.impl.AInt8TypeComputer;
import org.apache.asterix.om.typecomputer.impl.AIntervalTypeComputer;
import org.apache.asterix.om.typecomputer.impl.ALineTypeComputer;
-import org.apache.asterix.om.typecomputer.impl.AListTypeComputer;
+import org.apache.asterix.om.typecomputer.impl.AListOrNullTypeComputer;
+import org.apache.asterix.om.typecomputer.impl.AListFirstTypeComputer;
import org.apache.asterix.om.typecomputer.impl.APoint3DTypeComputer;
import org.apache.asterix.om.typecomputer.impl.APointTypeComputer;
import org.apache.asterix.om.typecomputer.impl.APolygonTypeComputer;
@@ -54,7 +55,6 @@
import org.apache.asterix.om.typecomputer.impl.AUUIDTypeComputer;
import org.apache.asterix.om.typecomputer.impl.AYearMonthDurationTypeComputer;
import org.apache.asterix.om.typecomputer.impl.AnyTypeComputer;
-import org.apache.asterix.om.typecomputer.impl.ArrayAppendTypeComputer;
import org.apache.asterix.om.typecomputer.impl.ArrayRepeatTypeComputer;
import org.apache.asterix.om.typecomputer.impl.BooleanFunctionTypeComputer;
import org.apache.asterix.om.typecomputer.impl.BooleanOnlyTypeComputer;
@@ -184,6 +184,12 @@
new FunctionIdentifier(FunctionConstants.ASTERIX_NS, "deep-equal",
2);
// array functions
+ public static final FunctionIdentifier ARRAY_REMOVE =
+ new FunctionIdentifier(FunctionConstants.ASTERIX_NS,
"array-remove", FunctionIdentifier.VARARGS);
+ public static final FunctionIdentifier ARRAY_PUT =
+ new FunctionIdentifier(FunctionConstants.ASTERIX_NS, "array-put",
FunctionIdentifier.VARARGS);
+ public static final FunctionIdentifier ARRAY_PREPEND =
+ new FunctionIdentifier(FunctionConstants.ASTERIX_NS,
"array-prepend", FunctionIdentifier.VARARGS);
public static final FunctionIdentifier ARRAY_APPEND =
new FunctionIdentifier(FunctionConstants.ASTERIX_NS,
"array-append", FunctionIdentifier.VARARGS);
public static final FunctionIdentifier ARRAY_POSITION =
@@ -194,6 +200,8 @@
new FunctionIdentifier(FunctionConstants.ASTERIX_NS,
"array-reverse", 1);
public static final FunctionIdentifier ARRAY_CONTAINS =
new FunctionIdentifier(FunctionConstants.ASTERIX_NS,
"array-contains", 2);
+ public static final FunctionIdentifier ARRAY_INSERT =
+ new FunctionIdentifier(FunctionConstants.ASTERIX_NS,
"array-insert", FunctionIdentifier.VARARGS);
// objects
public static final FunctionIdentifier RECORD_MERGE =
@@ -1470,11 +1478,15 @@
addFunction(WORD_TOKENS, OrderedListOfAStringTypeComputer.INSTANCE,
true);
// array functions
- addFunction(ARRAY_APPEND, ArrayAppendTypeComputer.INSTANCE, true);
+ addFunction(ARRAY_REMOVE, AListOrNullTypeComputer.INSTANCE_REMOVE,
true);
+ addFunction(ARRAY_PUT, AListOrNullTypeComputer.INSTANCE_PUT, true);
+ addFunction(ARRAY_PREPEND, AListOrNullTypeComputer.INSTANCE_PREPEND,
true);
+ addFunction(ARRAY_APPEND, AListOrNullTypeComputer.INSTANCE_APPEND,
true);
addFunction(ARRAY_POSITION, AInt32TypeComputer.INSTANCE, true);
addFunction(ARRAY_REPEAT, ArrayRepeatTypeComputer.INSTANCE, true);
- addFunction(ARRAY_REVERSE, AListTypeComputer.INSTANCE, true);
+ addFunction(ARRAY_REVERSE, AListFirstTypeComputer.INSTANCE, true);
addFunction(ARRAY_CONTAINS, ABooleanTypeComputer.INSTANCE, true);
+ addFunction(ARRAY_INSERT, AListOrNullTypeComputer.INSTANCE_INSERT,
true);
// objects
addFunction(RECORD_MERGE, RecordMergeTypeComputer.INSTANCE, true);
diff --git
a/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/typecomputer/impl/AListTypeComputer.java
b/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/typecomputer/impl/AListFirstTypeComputer.java
similarity index 84%
rename from
asterixdb/asterix-om/src/main/java/org/apache/asterix/om/typecomputer/impl/AListTypeComputer.java
rename to
asterixdb/asterix-om/src/main/java/org/apache/asterix/om/typecomputer/impl/AListFirstTypeComputer.java
index 92730f5..5ba7ba4 100644
---
a/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/typecomputer/impl/AListTypeComputer.java
+++
b/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/typecomputer/impl/AListFirstTypeComputer.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.AUnionType;
import org.apache.asterix.om.types.BuiltinType;
import org.apache.asterix.om.types.IAType;
import org.apache.hyracks.algebricks.common.exceptions.AlgebricksException;
@@ -29,10 +30,10 @@
* A type computer that returns the same list type as the presumably input
list at argument 0. If the argument is not a
* list, it returns "ANY".
*/
-public class AListTypeComputer extends AbstractResultTypeComputer {
- public static final AListTypeComputer INSTANCE = new AListTypeComputer();
+public class AListFirstTypeComputer extends AbstractResultTypeComputer {
+ public static final AListFirstTypeComputer INSTANCE = new
AListFirstTypeComputer();
- private AListTypeComputer() {
+ private AListFirstTypeComputer() {
}
@Override
@@ -41,7 +42,7 @@
switch (argType.getTypeTag()) {
case ARRAY:
case MULTISET:
- return argType;
+ return AUnionType.createNullableType(argType);
default:
return BuiltinType.ANY;
}
diff --git
a/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/typecomputer/impl/AListOrNullTypeComputer.java
b/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/typecomputer/impl/AListOrNullTypeComputer.java
new file mode 100755
index 0000000..2fb846f
--- /dev/null
+++
b/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/typecomputer/impl/AListOrNullTypeComputer.java
@@ -0,0 +1,83 @@
+/*
+ * 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.om.typecomputer.impl;
+
+import org.apache.asterix.common.exceptions.CompilationException;
+import org.apache.asterix.common.exceptions.ErrorCode;
+import org.apache.asterix.om.pointables.base.DefaultOpenFieldType;
+import org.apache.asterix.om.typecomputer.base.AbstractResultTypeComputer;
+import org.apache.asterix.om.types.ATypeTag;
+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;
+import org.apache.hyracks.algebricks.core.algebra.base.ILogicalExpression;
+import
org.apache.hyracks.algebricks.core.algebra.expressions.AbstractFunctionCallExpression;
+
+public class AListOrNullTypeComputer extends AbstractResultTypeComputer {
+ public static final AListOrNullTypeComputer INSTANCE_APPEND = new
AListOrNullTypeComputer(2, false, true, false);
+ public static final AListOrNullTypeComputer INSTANCE_PREPEND = new
AListOrNullTypeComputer(2, true, true, false);
+ public static final AListOrNullTypeComputer INSTANCE_INSERT = new
AListOrNullTypeComputer(3, false, true, false);
+ public static final AListOrNullTypeComputer INSTANCE_REMOVE = new
AListOrNullTypeComputer(2, false, false, true);
+ public static final AListOrNullTypeComputer INSTANCE_PUT = new
AListOrNullTypeComputer(2, false, true, true);
+
+ private final int minNumArgs;
+ private final boolean listIsLast;
+ private final boolean makeOpen;
+ private final boolean nullInNullOut;
+
+ protected AListOrNullTypeComputer(int minNumArgs, boolean listIsLast,
boolean makeOpen, boolean nullInNullOut) {
+ this.minNumArgs = minNumArgs;
+ this.listIsLast = listIsLast;
+ this.makeOpen = makeOpen;
+ this.nullInNullOut = nullInNullOut;
+ }
+
+ @Override
+ protected IAType getResultType(ILogicalExpression expr, IAType...
strippedInputTypes) throws AlgebricksException {
+ if (strippedInputTypes.length < minNumArgs) {
+ String functionName = ((AbstractFunctionCallExpression)
expr).getFunctionIdentifier().getName();
+ throw new
CompilationException(ErrorCode.COMPILATION_INVALID_NUM_OF_ARGS,
expr.getSourceLocation(),
+ minNumArgs, functionName);
+ }
+ // output type should be the same as as the type tag at [list index].
The output type is nullable
+ // since the output could be null due to other invalid arguments or
the tag at [list index] itself is not list
+ int listIndex = 0;
+ if (listIsLast) {
+ listIndex = strippedInputTypes.length - 1;
+ }
+
+ IAType listType = strippedInputTypes[listIndex];
+ if (listType.getTypeTag() == ATypeTag.ARRAY) {
+ return makeOpen ?
AUnionType.createUnknownableType(DefaultOpenFieldType.NESTED_OPEN_AORDERED_LIST_TYPE)
+ : AUnionType.createUnknownableType(listType);
+ } else if (listType.getTypeTag() == ATypeTag.MULTISET) {
+ return makeOpen ?
AUnionType.createUnknownableType(DefaultOpenFieldType.NESTED_OPEN_AUNORDERED_LIST_TYPE)
+ : AUnionType.createUnknownableType(listType);
+ } else {
+ return BuiltinType.ANY;
+ }
+ }
+
+ @Override
+ protected boolean propagateNullAndMissing() {
+ return nullInNullOut;
+ }
+}
diff --git
a/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/typecomputer/impl/ArrayAppendTypeComputer.java
b/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/typecomputer/impl/ArrayAppendTypeComputer.java
deleted file mode 100755
index f2fed42..0000000
---
a/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/typecomputer/impl/ArrayAppendTypeComputer.java
+++ /dev/null
@@ -1,54 +0,0 @@
-/*
- * 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.om.typecomputer.impl;
-
-import org.apache.asterix.common.exceptions.CompilationException;
-import org.apache.asterix.common.exceptions.ErrorCode;
-import org.apache.asterix.om.pointables.base.DefaultOpenFieldType;
-import org.apache.asterix.om.typecomputer.base.AbstractResultTypeComputer;
-import org.apache.asterix.om.types.ATypeTag;
-import org.apache.asterix.om.types.BuiltinType;
-import org.apache.asterix.om.types.IAType;
-import org.apache.hyracks.algebricks.common.exceptions.AlgebricksException;
-import org.apache.hyracks.algebricks.core.algebra.base.ILogicalExpression;
-import
org.apache.hyracks.algebricks.core.algebra.expressions.AbstractFunctionCallExpression;
-
-public class ArrayAppendTypeComputer extends AbstractResultTypeComputer {
-
- public static final ArrayAppendTypeComputer INSTANCE = new
ArrayAppendTypeComputer();
-
- @Override
- protected IAType getResultType(ILogicalExpression expr, IAType...
strippedInputTypes) throws AlgebricksException {
- if (strippedInputTypes.length < 2) {
- String functionName = ((AbstractFunctionCallExpression)
expr).getFunctionIdentifier().getName();
- throw new
CompilationException(ErrorCode.COMPILATION_INVALID_NUM_OF_ARGS,
expr.getSourceLocation(), 2,
- functionName);
- }
- // type tag at [0] should be array or multiset.
- ATypeTag typeTag = strippedInputTypes[0].getTypeTag();
- if (typeTag == ATypeTag.ARRAY) {
- return DefaultOpenFieldType.NESTED_OPEN_AORDERED_LIST_TYPE;
- } else if (typeTag == ATypeTag.MULTISET) {
- return DefaultOpenFieldType.NESTED_OPEN_AUNORDERED_LIST_TYPE;
- } else {
- return BuiltinType.ANY;
- }
- }
-}
diff --git
a/asterixdb/asterix-om/src/test/java/org/apache/asterix/om/typecomputer/TypeComputerTest.java
b/asterixdb/asterix-om/src/test/java/org/apache/asterix/om/typecomputer/TypeComputerTest.java
index 1ff62b9..ced58a7 100644
---
a/asterixdb/asterix-om/src/test/java/org/apache/asterix/om/typecomputer/TypeComputerTest.java
+++
b/asterixdb/asterix-om/src/test/java/org/apache/asterix/om/typecomputer/TypeComputerTest.java
@@ -63,6 +63,7 @@
exceptionalTypeComputers.add("NullableDoubleTypeComputer");
exceptionalTypeComputers.add("RecordMergeTypeComputer");
exceptionalTypeComputers.add("BooleanOrMissingTypeComputer");
+ exceptionalTypeComputers.add("AListOrNullTypeComputer");
// Tests all usual type computers.
Reflections reflections = new
Reflections("org.apache.asterix.om.typecomputer", new SubTypesScanner(false));
diff --git
a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/AbstractArrayAddRemoveEval.java
b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/AbstractArrayAddRemoveEval.java
new file mode 100755
index 0000000..57a642f
--- /dev/null
+++
b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/AbstractArrayAddRemoveEval.java
@@ -0,0 +1,193 @@
+/*
+ * 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;
+
+import static
org.apache.asterix.om.types.EnumDeserializer.ATYPETAGDESERIALIZER;
+
+import java.io.IOException;
+
+import org.apache.asterix.builders.IAsterixListBuilder;
+import org.apache.asterix.builders.OrderedListBuilder;
+import org.apache.asterix.builders.UnorderedListBuilder;
+import org.apache.asterix.om.pointables.base.DefaultOpenFieldType;
+import org.apache.asterix.om.pointables.nonvisitor.AListPointable;
+import org.apache.asterix.om.types.ATypeTag;
+import org.apache.asterix.om.types.AbstractCollectionType;
+import org.apache.asterix.om.types.IAType;
+import org.apache.asterix.runtime.evaluators.common.ListAccessor;
+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.ErrorCode;
+import org.apache.hyracks.api.exceptions.HyracksDataException;
+import org.apache.hyracks.api.exceptions.SourceLocation;
+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 abstract class AbstractArrayAddRemoveEval implements IScalarEvaluator {
+ private final IAType[] argTypes;
+ private final ArrayBackedValueStorage storage;
+ private final AListPointable listArg;
+ private final IPointable[] valuesArgs;
+ private final IScalarEvaluator listArgEval;
+ private final IScalarEvaluator[] valuesEval;
+ private final SourceLocation sourceLocation;
+ private final int listOffset;
+ private final int valuesOffset;
+ private final boolean comparesValues;
+ private final boolean makeOpen;
+ private final boolean acceptNullValues;
+
+ public AbstractArrayAddRemoveEval(IScalarEvaluatorFactory[] args,
IHyracksTaskContext ctx, int listOffset,
+ int valuesOffset, int numValues, IAType[] argTypes, boolean
comparesValues, SourceLocation sourceLocation,
+ boolean makeOpen, boolean acceptNullValues) throws
HyracksDataException {
+ this.listOffset = listOffset;
+ this.valuesOffset = valuesOffset;
+ this.argTypes = argTypes;
+ this.comparesValues = comparesValues;
+ this.sourceLocation = sourceLocation;
+ this.makeOpen = makeOpen;
+ this.acceptNullValues = acceptNullValues;
+ storage = new ArrayBackedValueStorage();
+ listArg = new AListPointable();
+ listArgEval = args[listOffset].createScalarEvaluator(ctx);
+ valuesArgs = new IPointable[numValues];
+ valuesEval = new IScalarEvaluator[numValues];
+ for (int i = 0; i < numValues; i++) {
+ valuesArgs[i] = new VoidPointable();
+ valuesEval[i] = args[i + valuesOffset].createScalarEvaluator(ctx);
+ }
+ }
+
+ /**
+ * @param listArg the list into which to insert the items at the
calculated returned position
+ * @param tuple the tuple that contains the arguments including position
argument
+ * @return -1 if position value is missing, -2 if null, otherwise should
return the adjusted position value, >= 0
+ */
+ protected abstract int getPosition(IFrameTupleReference tuple,
AListPointable listArg) throws HyracksDataException;
+
+ @Override
+ public void evaluate(IFrameTupleReference tuple, IPointable result) throws
HyracksDataException {
+ // get the list argument, 1st or last argument, make sure it's a list
+ listArgEval.evaluate(tuple, listArg);
+ ATypeTag listArgTag =
ATYPETAGDESERIALIZER.deserialize(listArg.getByteArray()[listArg.getStartOffset()]);
+
+ // evaluate the position argument if provided by some functions
+ int adjustedPosition = getPosition(tuple, listArg);
+
+ if (listArgTag == ATypeTag.MISSING || adjustedPosition == -1) {
+ PointableHelper.setMissing(result);
+ return;
+ }
+
+ boolean returnNull = false;
+ if (!listArgTag.isListType() || adjustedPosition < -1) {
+ returnNull = true;
+ }
+
+ // evaluate values to be added/removed
+ ATypeTag valueTag;
+ IAType defaultOpenType;
+ boolean encounteredNonPrimitive = false;
+ CastTypeEvaluator caster = new CastTypeEvaluator();
+ for (int i = 0; i < valuesEval.length; i++) {
+ // cast val to open if needed. don't cast if function will return
null anyway, e.g. list arg was not list
+ defaultOpenType =
DefaultOpenFieldType.getDefaultOpenFieldType(argTypes[i +
valuesOffset].getTypeTag());
+ if (defaultOpenType != null && !returnNull) {
+ caster.reset(defaultOpenType, argTypes[i + valuesOffset],
valuesEval[i]);
+ caster.evaluate(tuple, valuesArgs[i]);
+ } else {
+ valuesEval[i].evaluate(tuple, valuesArgs[i]);
+ }
+ valueTag =
ATYPETAGDESERIALIZER.deserialize(valuesArgs[i].getByteArray()[valuesArgs[i].getStartOffset()]);
+ // for now, we don't support deep equality of object/lists. Throw
an error if the value is of these types
+ if (comparesValues && valueTag.isDerivedType()) {
+ encounteredNonPrimitive = true;
+ }
+ if (valueTag == ATypeTag.MISSING) {
+ PointableHelper.setMissing(result);
+ return;
+ }
+ if (!acceptNullValues && valueTag == ATypeTag.NULL) {
+ returnNull = true;
+ }
+ }
+
+ if (returnNull) {
+ PointableHelper.setNull(result);
+ return;
+ }
+
+ if (encounteredNonPrimitive) {
+ throw
HyracksDataException.create(ErrorCode.CANNOT_COMPARE_COMPLEX, sourceLocation);
+ }
+ // all arguments are valid
+ AbstractCollectionType listType = (AbstractCollectionType)
argTypes[listOffset];
+ IAsterixListBuilder listBuilder;
+ // create the new list to be returned. cast the input list and make it
open if required
+ if (listArgTag == ATypeTag.ARRAY) {
+ listBuilder = new OrderedListBuilder();
+ if (makeOpen) {
+ listType = DefaultOpenFieldType.NESTED_OPEN_AORDERED_LIST_TYPE;
+ caster.reset(listType, argTypes[listOffset], listArgEval);
+ caster.evaluate(tuple, listArg);
+ }
+ } else {
+ listBuilder = new UnorderedListBuilder();
+ if (makeOpen) {
+ listType =
DefaultOpenFieldType.NESTED_OPEN_AUNORDERED_LIST_TYPE;
+ caster.reset(listType, argTypes[listOffset], listArgEval);
+ caster.evaluate(tuple, listArg);
+ }
+ }
+
+ listBuilder.reset(listType);
+ ListAccessor listAccessor = new ListAccessor();
+ listAccessor.reset(listArg.getByteArray(), listArg.getStartOffset());
+ try {
+ processList(listAccessor, listBuilder, valuesArgs,
adjustedPosition);
+ storage.reset();
+ listBuilder.write(storage.getDataOutput(), true);
+ result.set(storage);
+ } catch (IOException e) {
+ throw HyracksDataException.create(e);
+ }
+ }
+
+ protected void processList(ListAccessor listAccessor, IAsterixListBuilder
listBuilder, IPointable[] values,
+ int position) throws IOException {
+ int i;
+ for (i = 0; i < position; i++) {
+ storage.reset();
+ listAccessor.writeItem(i, storage.getDataOutput());
+ listBuilder.addItem(storage);
+ }
+ // insert the values arguments
+ for (IPointable addedValues : values) {
+ listBuilder.addItem(addedValues);
+ }
+ for (; i < listAccessor.size(); i++) {
+ storage.reset();
+ listAccessor.writeItem(i, storage.getDataOutput());
+ listBuilder.addItem(storage);
+ }
+ }
+}
diff --git
a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/ArrayAppendDescriptor.java
b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/ArrayAppendDescriptor.java
index 3792b8e..524b72e 100755
---
a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/ArrayAppendDescriptor.java
+++
b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/ArrayAppendDescriptor.java
@@ -18,24 +18,15 @@
*/
package org.apache.asterix.runtime.evaluators.functions;
-import static
org.apache.asterix.om.types.EnumDeserializer.ATYPETAGDESERIALIZER;
-
-import java.io.IOException;
-import java.util.Arrays;
-
-import org.apache.asterix.builders.IAsterixListBuilder;
-import org.apache.asterix.builders.OrderedListBuilder;
-import org.apache.asterix.builders.UnorderedListBuilder;
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.base.DefaultOpenFieldType;
+import org.apache.asterix.om.pointables.nonvisitor.AListPointable;
import org.apache.asterix.om.types.ATypeTag;
-import org.apache.asterix.om.types.AbstractCollectionType;
+import org.apache.asterix.om.types.EnumDeserializer;
import org.apache.asterix.om.types.IAType;
import
org.apache.asterix.runtime.evaluators.base.AbstractScalarFunctionDynamicDescriptor;
-import org.apache.asterix.runtime.evaluators.common.ListAccessor;
import org.apache.asterix.runtime.functions.FunctionTypeInferers;
import org.apache.hyracks.algebricks.common.exceptions.AlgebricksException;
import org.apache.hyracks.algebricks.core.algebra.functions.FunctionIdentifier;
@@ -43,9 +34,6 @@
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 ArrayAppendDescriptor extends
AbstractScalarFunctionDynamicDescriptor {
@@ -84,93 +72,24 @@
@Override
public void setImmutableStates(Object... states) {
- argTypes = Arrays.copyOf(states, states.length, IAType[].class);
+ argTypes = (IAType[]) states;
}
- public class ArrayAppendFunction implements IScalarEvaluator {
- private final ArrayBackedValueStorage storage;
- private final IPointable listArg;
- private final IPointable[] appendedValues;
- private final IScalarEvaluator listArgEval;
- private final IScalarEvaluator[] appendedValuesEval;
+ public class ArrayAppendFunction extends AbstractArrayAddRemoveEval {
public ArrayAppendFunction(IScalarEvaluatorFactory[] args,
IHyracksTaskContext ctx)
throws HyracksDataException {
- storage = new ArrayBackedValueStorage();
- listArg = new VoidPointable();
- listArgEval = args[0].createScalarEvaluator(ctx);
- appendedValues = new IPointable[args.length - 1];
- appendedValuesEval = new IScalarEvaluator[args.length - 1];
- for (int i = 1; i < args.length; i++) {
- appendedValues[i - 1] = new VoidPointable();
- appendedValuesEval[i - 1] = args[i].createScalarEvaluator(ctx);
- }
+ super(args, ctx, 0, 1, args.length - 1, argTypes, false,
sourceLoc, true, true);
}
@Override
- public void evaluate(IFrameTupleReference tuple, IPointable result)
throws HyracksDataException {
- // get the list argument, 1st argument, make sure it's a list
- listArgEval.evaluate(tuple, listArg);
- byte listArgType =
listArg.getByteArray()[listArg.getStartOffset()];
-
- CastTypeEvaluator caster = null;
- AbstractCollectionType listType = null;
- IAsterixListBuilder listBuilder = null;
- // create the new list to be returned. The item type is always
"ANY"
- // cast the input list and make it open
- if (listArgType == ATypeTag.SERIALIZED_ORDEREDLIST_TYPE_TAG) {
- listBuilder = new OrderedListBuilder();
- listType = DefaultOpenFieldType.NESTED_OPEN_AORDERED_LIST_TYPE;
- caster = new CastTypeEvaluator(listType, argTypes[0],
listArgEval);
- caster.evaluate(tuple, listArg);
- } else if (listArgType ==
ATypeTag.SERIALIZED_UNORDEREDLIST_TYPE_TAG) {
- listBuilder = new UnorderedListBuilder();
- listType =
DefaultOpenFieldType.NESTED_OPEN_AUNORDERED_LIST_TYPE;
- caster = new CastTypeEvaluator(listType, argTypes[0],
listArgEval);
- caster.evaluate(tuple, listArg);
+ protected int getPosition(IFrameTupleReference tuple, AListPointable
listArg) throws HyracksDataException {
+ ATypeTag listTag =
+
EnumDeserializer.ATYPETAGDESERIALIZER.deserialize(listArg.getByteArray()[listArg.getStartOffset()]);
+ if (listTag.isListType()) {
+ return listArg.getItemCount();
}
- // else, don't return null right away. evaluate rest of args as
some may be missing, return missing instead
- IAType defaultOpenType;
- for (int i = 0; i < appendedValuesEval.length; i++) {
- // cast to open if necessary
- defaultOpenType =
DefaultOpenFieldType.getDefaultOpenFieldType(argTypes[i + 1].getTypeTag());
- if (defaultOpenType != null && caster != null) {
- caster.reset(defaultOpenType, argTypes[i + 1],
appendedValuesEval[i]);
- caster.evaluate(tuple, appendedValues[i]);
- } else {
- // either no casting is needed (e.g. int and the like) or
evaluate normally for the below case:
- // when caster == null, it means the first arg was not a
list and a null would be returned but
- // evaluate values to be appended normally in case missing
exists and return missing instead of null
- appendedValuesEval[i].evaluate(tuple, appendedValues[i]);
- }
- }
-
- if (!ATYPETAGDESERIALIZER.deserialize(listArgType).isListType()) {
- PointableHelper.setNull(result);
- return;
- }
-
- // arguments are good: no nulls/missings and 1st arg is a list
- listBuilder.reset(listType);
- ListAccessor listAccessor = new ListAccessor();
- listAccessor.reset(listArg.getByteArray(),
listArg.getStartOffset());
- try {
- // get the list items one by one and append to the new list
- for (int i = 0; i < listAccessor.size(); i++) {
- storage.reset();
- listAccessor.writeItem(i, storage.getDataOutput());
- listBuilder.addItem(storage);
- }
- // append the values arguments
- for (IPointable appendedValue : appendedValues) {
- listBuilder.addItem(appendedValue);
- }
- storage.reset();
- listBuilder.write(storage.getDataOutput(), true);
- result.set(storage);
- } catch (IOException e) {
- throw HyracksDataException.create(e);
- }
+ return -2;
}
}
}
diff --git
a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/ArrayInsertDescriptor.java
b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/ArrayInsertDescriptor.java
new file mode 100755
index 0000000..b7af519
--- /dev/null
+++
b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/ArrayInsertDescriptor.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;
+
+import static
org.apache.asterix.om.types.EnumDeserializer.ATYPETAGDESERIALIZER;
+
+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.AListPointable;
+import org.apache.asterix.om.types.ATypeTag;
+import org.apache.asterix.om.types.EnumDeserializer;
+import org.apache.asterix.om.types.IAType;
+import org.apache.asterix.om.types.hierachy.ATypeHierarchy;
+import
org.apache.asterix.runtime.evaluators.base.AbstractScalarFunctionDynamicDescriptor;
+import org.apache.asterix.runtime.functions.FunctionTypeInferers;
+import org.apache.hyracks.algebricks.common.exceptions.AlgebricksException;
+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.primitive.TaggedValuePointable;
+import org.apache.hyracks.dataflow.common.data.accessors.IFrameTupleReference;
+
+public class ArrayInsertDescriptor extends
AbstractScalarFunctionDynamicDescriptor {
+ private static final long serialVersionUID = 1L;
+ private IAType[] argTypes;
+
+ public static final IFunctionDescriptorFactory FACTORY = new
IFunctionDescriptorFactory() {
+ @Override
+ public IFunctionDescriptor createFunctionDescriptor() {
+ return new ArrayInsertDescriptor();
+ }
+
+ @Override
+ public IFunctionTypeInferer createFunctionTypeInferer() {
+ return FunctionTypeInferers.SET_ARGUMENTS_TYPE;
+ }
+ };
+
+ @Override
+ public FunctionIdentifier getIdentifier() {
+ return BuiltinFunctions.ARRAY_INSERT;
+ }
+
+ @Override
+ public IScalarEvaluatorFactory createEvaluatorFactory(final
IScalarEvaluatorFactory[] args)
+ throws AlgebricksException {
+ return new IScalarEvaluatorFactory() {
+ private static final long serialVersionUID = 1L;
+
+ @Override
+ public IScalarEvaluator createScalarEvaluator(final
IHyracksTaskContext ctx) throws HyracksDataException {
+ return new ArrayInsertFunction(args, ctx);
+ }
+ };
+ }
+
+ @Override
+ public void setImmutableStates(Object... states) {
+ argTypes = (IAType[]) states;
+ }
+
+ public class ArrayInsertFunction extends AbstractArrayAddRemoveEval {
+ private final TaggedValuePointable positionArg;
+ private final IScalarEvaluator positionArgEval;
+
+ public ArrayInsertFunction(IScalarEvaluatorFactory[] args,
IHyracksTaskContext ctx)
+ throws HyracksDataException {
+ super(args, ctx, 0, 2, args.length - 2, argTypes, false,
sourceLoc, true, true);
+ positionArg = new TaggedValuePointable();
+ positionArgEval = args[1].createScalarEvaluator(ctx);
+ }
+
+ @Override
+ protected int getPosition(IFrameTupleReference tuple, AListPointable
listArg) throws HyracksDataException {
+ positionArgEval.evaluate(tuple, positionArg);
+ if (positionArg.getTag() == ATypeTag.SERIALIZED_MISSING_TYPE_TAG) {
+ return -1;
+ }
+ ATypeTag listTag =
+
EnumDeserializer.ATYPETAGDESERIALIZER.deserialize(listArg.getByteArray()[listArg.getStartOffset()]);
+ int position;
+ if (!ATypeHierarchy.isCompatible(ATypeTag.INTEGER,
ATYPETAGDESERIALIZER.deserialize(positionArg.getTag()))
+ || !listTag.isListType()) {
+ return -2;
+ } else {
+ String name = getIdentifier().getName();
+ position = ATypeHierarchy.getIntegerValue(name, 1,
positionArg.getByteArray(),
+ positionArg.getStartOffset());
+ int listSize = listArg.getItemCount();
+ // adjust position for negative positions
+ if (position < 0) {
+ position = listSize + position;
+ }
+ // position should always be positive now and should be within
[0-list_size]
+ if (position < 0 || position > listSize) {
+ return -2;
+ }
+ return position;
+ }
+ }
+ }
+}
diff --git
a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/ArrayPrependDescriptor.java
b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/ArrayPrependDescriptor.java
new file mode 100755
index 0000000..6fa3ab7
--- /dev/null
+++
b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/ArrayPrependDescriptor.java
@@ -0,0 +1,88 @@
+/*
+ * 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;
+
+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.AListPointable;
+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.common.exceptions.AlgebricksException;
+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.dataflow.common.data.accessors.IFrameTupleReference;
+
+public class ArrayPrependDescriptor extends
AbstractScalarFunctionDynamicDescriptor {
+ private static final long serialVersionUID = 1L;
+ private IAType[] argTypes;
+
+ public static final IFunctionDescriptorFactory FACTORY = new
IFunctionDescriptorFactory() {
+ @Override
+ public IFunctionDescriptor createFunctionDescriptor() {
+ return new ArrayPrependDescriptor();
+ }
+
+ @Override
+ public IFunctionTypeInferer createFunctionTypeInferer() {
+ return FunctionTypeInferers.SET_ARGUMENTS_TYPE;
+ }
+ };
+
+ @Override
+ public FunctionIdentifier getIdentifier() {
+ return BuiltinFunctions.ARRAY_PREPEND;
+ }
+
+ @Override
+ public IScalarEvaluatorFactory createEvaluatorFactory(final
IScalarEvaluatorFactory[] args)
+ throws AlgebricksException {
+ return new IScalarEvaluatorFactory() {
+ private static final long serialVersionUID = 1L;
+
+ @Override
+ public IScalarEvaluator createScalarEvaluator(final
IHyracksTaskContext ctx) throws HyracksDataException {
+ return new ArrayPrependFunction(args, ctx);
+ }
+ };
+ }
+
+ @Override
+ public void setImmutableStates(Object... states) {
+ argTypes = (IAType[]) states;
+ }
+
+ public class ArrayPrependFunction extends AbstractArrayAddRemoveEval {
+
+ public ArrayPrependFunction(IScalarEvaluatorFactory[] args,
IHyracksTaskContext ctx)
+ throws HyracksDataException {
+ super(args, ctx, args.length - 1, 0, args.length - 1, argTypes,
false, sourceLoc, true, true);
+ }
+
+ @Override
+ protected int getPosition(IFrameTupleReference tuple, AListPointable
listArg) throws HyracksDataException {
+ return 0;
+ }
+ }
+}
diff --git
a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/ArrayPutDescriptor.java
b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/ArrayPutDescriptor.java
new file mode 100755
index 0000000..b24a59d
--- /dev/null
+++
b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/ArrayPutDescriptor.java
@@ -0,0 +1,133 @@
+/*
+ * 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;
+
+import java.io.IOException;
+
+import org.apache.asterix.builders.IAsterixListBuilder;
+import
org.apache.asterix.dataflow.data.nontagged.comparators.AObjectAscBinaryComparatorFactory;
+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.AListPointable;
+import org.apache.asterix.om.types.ATypeTag;
+import org.apache.asterix.om.types.EnumDeserializer;
+import org.apache.asterix.om.types.IAType;
+import
org.apache.asterix.runtime.evaluators.base.AbstractScalarFunctionDynamicDescriptor;
+import org.apache.asterix.runtime.evaluators.common.ListAccessor;
+import org.apache.asterix.runtime.functions.FunctionTypeInferers;
+import org.apache.hyracks.algebricks.common.exceptions.AlgebricksException;
+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.IBinaryComparator;
+import org.apache.hyracks.api.exceptions.HyracksDataException;
+import org.apache.hyracks.data.std.api.IPointable;
+import org.apache.hyracks.data.std.util.ArrayBackedValueStorage;
+import org.apache.hyracks.dataflow.common.data.accessors.IFrameTupleReference;
+
+public class ArrayPutDescriptor extends
AbstractScalarFunctionDynamicDescriptor {
+ private static final long serialVersionUID = 1L;
+ private IAType[] argTypes;
+
+ public static final IFunctionDescriptorFactory FACTORY = new
IFunctionDescriptorFactory() {
+ @Override
+ public IFunctionDescriptor createFunctionDescriptor() {
+ return new ArrayPutDescriptor();
+ }
+
+ @Override
+ public IFunctionTypeInferer createFunctionTypeInferer() {
+ return FunctionTypeInferers.SET_ARGUMENTS_TYPE;
+ }
+ };
+
+ @Override
+ public FunctionIdentifier getIdentifier() {
+ return BuiltinFunctions.ARRAY_PUT;
+ }
+
+ @Override
+ public IScalarEvaluatorFactory createEvaluatorFactory(final
IScalarEvaluatorFactory[] args)
+ throws AlgebricksException {
+ return new IScalarEvaluatorFactory() {
+ private static final long serialVersionUID = 1L;
+
+ @Override
+ public IScalarEvaluator createScalarEvaluator(final
IHyracksTaskContext ctx) throws HyracksDataException {
+ return new ArrayPutFunction(args, ctx);
+ }
+ };
+ }
+
+ @Override
+ public void setImmutableStates(Object... states) {
+ argTypes = (IAType[]) states;
+ }
+
+ public class ArrayPutFunction extends AbstractArrayAddRemoveEval {
+ private final ArrayBackedValueStorage storage;
+ private final IBinaryComparator comp;
+
+ public ArrayPutFunction(IScalarEvaluatorFactory[] args,
IHyracksTaskContext ctx) throws HyracksDataException {
+ super(args, ctx, 0, 1, args.length - 1, argTypes, true, sourceLoc,
true, false);
+ comp =
AObjectAscBinaryComparatorFactory.INSTANCE.createBinaryComparator();
+ storage = new ArrayBackedValueStorage();
+ }
+
+ @Override
+ protected int getPosition(IFrameTupleReference tuple, AListPointable
listArg) throws HyracksDataException {
+ ATypeTag listTag =
+
EnumDeserializer.ATYPETAGDESERIALIZER.deserialize(listArg.getByteArray()[listArg.getStartOffset()]);
+ if (listTag.isListType()) {
+ return listArg.getItemCount();
+ }
+ return -2;
+ }
+
+ @Override
+ protected void processList(ListAccessor listAccessor,
IAsterixListBuilder listBuilder, IPointable[] values,
+ int position) throws IOException {
+ boolean[] dontAdd = new boolean[values.length];
+ // get the list items one by one and append to the new list
+ for (int i = 0; i < listAccessor.size(); i++) {
+ storage.reset();
+ listAccessor.writeItem(i, storage.getDataOutput());
+ listBuilder.addItem(storage);
+ // mark the equal values to skip adding them
+ for (int j = 0; j < values.length; j++) {
+ if (!dontAdd[j]
+ && comp.compare(storage.getByteArray(),
storage.getStartOffset(), storage.getLength(),
+ values[j].getByteArray(),
values[j].getStartOffset(), values[j].getLength()) == 0) {
+ dontAdd[j] = true;
+ }
+ // skip comparison if the value is already marked
+ }
+ }
+ // append the values arguments only if they are not already
present in the list, i.e. not marked
+ for (int i = 0; i < values.length; i++) {
+ if (!dontAdd[i]) {
+ listBuilder.addItem(values[i]);
+ }
+ }
+ }
+ }
+}
diff --git
a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/ArrayRemoveDescriptor.java
b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/ArrayRemoveDescriptor.java
new file mode 100755
index 0000000..c2b5178
--- /dev/null
+++
b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/ArrayRemoveDescriptor.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;
+
+import java.io.IOException;
+
+import org.apache.asterix.builders.IAsterixListBuilder;
+import
org.apache.asterix.dataflow.data.nontagged.comparators.AObjectAscBinaryComparatorFactory;
+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.AListPointable;
+import org.apache.asterix.om.types.IAType;
+import
org.apache.asterix.runtime.evaluators.base.AbstractScalarFunctionDynamicDescriptor;
+import org.apache.asterix.runtime.evaluators.common.ListAccessor;
+import org.apache.asterix.runtime.functions.FunctionTypeInferers;
+import org.apache.hyracks.algebricks.common.exceptions.AlgebricksException;
+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.IBinaryComparator;
+import org.apache.hyracks.api.exceptions.HyracksDataException;
+import org.apache.hyracks.data.std.api.IPointable;
+import org.apache.hyracks.data.std.util.ArrayBackedValueStorage;
+import org.apache.hyracks.dataflow.common.data.accessors.IFrameTupleReference;
+
+public class ArrayRemoveDescriptor extends
AbstractScalarFunctionDynamicDescriptor {
+ private static final long serialVersionUID = 1L;
+ private IAType[] argTypes;
+
+ public static final IFunctionDescriptorFactory FACTORY = new
IFunctionDescriptorFactory() {
+ @Override
+ public IFunctionDescriptor createFunctionDescriptor() {
+ return new ArrayRemoveDescriptor();
+ }
+
+ @Override
+ public IFunctionTypeInferer createFunctionTypeInferer() {
+ return FunctionTypeInferers.SET_ARGUMENTS_TYPE;
+ }
+ };
+
+ @Override
+ public FunctionIdentifier getIdentifier() {
+ return BuiltinFunctions.ARRAY_REMOVE;
+ }
+
+ @Override
+ public IScalarEvaluatorFactory createEvaluatorFactory(final
IScalarEvaluatorFactory[] args)
+ throws AlgebricksException {
+ return new IScalarEvaluatorFactory() {
+ private static final long serialVersionUID = 1L;
+
+ @Override
+ public IScalarEvaluator createScalarEvaluator(final
IHyracksTaskContext ctx) throws HyracksDataException {
+ return new ArrayRemoveFunction(args, ctx);
+ }
+ };
+ }
+
+ @Override
+ public void setImmutableStates(Object... states) {
+ argTypes = (IAType[]) states;
+ }
+
+ public class ArrayRemoveFunction extends AbstractArrayAddRemoveEval {
+ private final ArrayBackedValueStorage storage;
+ private final IBinaryComparator comp;
+
+ public ArrayRemoveFunction(IScalarEvaluatorFactory[] args,
IHyracksTaskContext ctx)
+ throws HyracksDataException {
+ super(args, ctx, 0, 1, args.length - 1, argTypes, true, sourceLoc,
false, false);
+ storage = new ArrayBackedValueStorage();
+ comp =
AObjectAscBinaryComparatorFactory.INSTANCE.createBinaryComparator();
+ }
+
+ @Override
+ protected int getPosition(IFrameTupleReference tuple, AListPointable
listArg) throws HyracksDataException {
+ return 0;
+ }
+
+ @Override
+ protected void processList(ListAccessor listAccessor,
IAsterixListBuilder listBuilder, IPointable[] removedVals,
+ int position) throws IOException {
+ // get the list items one by one and append to the new list only
if the list item is not in removed list
+ boolean addItem;
+ for (int i = 0; i < listAccessor.size(); i++) {
+ storage.reset();
+ listAccessor.writeItem(i, storage.getDataOutput());
+ addItem = true;
+ for (IPointable removedVal : removedVals) {
+ if (comp.compare(storage.getByteArray(),
storage.getStartOffset(), storage.getLength(),
+ removedVal.getByteArray(),
removedVal.getStartOffset(), removedVal.getLength()) == 0) {
+ addItem = false;
+ break;
+ }
+ }
+ if (addItem) {
+ listBuilder.addItem(storage);
+ }
+ }
+ }
+ }
+}
diff --git
a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/CastTypeEvaluator.java
b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/CastTypeEvaluator.java
index 7e31951..d1879b2 100644
---
a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/CastTypeEvaluator.java
+++
b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/CastTypeEvaluator.java
@@ -37,20 +37,18 @@
private IScalarEvaluator argEvaluator;
private final IPointable argPointable = new VoidPointable();
-
private final PointableAllocator allocator = new PointableAllocator();
private IVisitablePointable inputPointable;
private IVisitablePointable resultPointable;
+ private final ACastVisitor castVisitor = createCastVisitor();
+ private final Triple<IVisitablePointable, IAType, Boolean> arg = new
Triple<>(null, null, null);
- private final ACastVisitor castVisitor;
- private final Triple<IVisitablePointable, IAType, Boolean> arg;
+ public CastTypeEvaluator() {
+ // reset() should be called after using this constructor before
calling any method
+ }
public CastTypeEvaluator(IAType reqType, IAType inputType,
IScalarEvaluator argEvaluator) {
- this.argEvaluator = argEvaluator;
- this.inputPointable = allocatePointable(inputType, reqType);
- this.resultPointable = allocatePointable(reqType, inputType);
- this.arg = new Triple<>(resultPointable, reqType, Boolean.FALSE);
- this.castVisitor = createCastVisitor();
+ reset(reqType, inputType, argEvaluator);
}
public void reset(IAType reqType, IAType inputType, IScalarEvaluator
argEvaluator) {
@@ -59,6 +57,7 @@
this.resultPointable = allocatePointable(reqType, inputType);
this.arg.first = resultPointable;
this.arg.second = reqType;
+ this.arg.third = Boolean.FALSE;
}
protected ACastVisitor createCastVisitor() {
diff --git
a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/PointableHelper.java
b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/PointableHelper.java
index 004e50a..48b1785 100644
---
a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/PointableHelper.java
+++
b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/PointableHelper.java
@@ -43,7 +43,7 @@
public class PointableHelper {
private static final byte[] NULL_BYTES = new byte[] {
ATypeTag.SERIALIZED_NULL_TYPE_TAG };
-
+ private static final byte[] MISSING_BYTES = new byte[] {
ATypeTag.SERIALIZED_MISSING_TYPE_TAG };
private final UTF8StringWriter utf8Writer;
public PointableHelper() {
@@ -135,4 +135,8 @@
public static void setNull(IPointable pointable) {
pointable.set(NULL_BYTES, 0, NULL_BYTES.length);
}
+
+ public static void setMissing(IPointable pointable) {
+ pointable.set(MISSING_BYTES, 0, MISSING_BYTES.length);
+ }
}
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 199cc40..519cb86 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
@@ -145,7 +145,11 @@
import
org.apache.asterix.runtime.evaluators.functions.AnyCollectionMemberDescriptor;
import org.apache.asterix.runtime.evaluators.functions.ArrayAppendDescriptor;
import org.apache.asterix.runtime.evaluators.functions.ArrayContainsDescriptor;
+import org.apache.asterix.runtime.evaluators.functions.ArrayInsertDescriptor;
import org.apache.asterix.runtime.evaluators.functions.ArrayPositionDescriptor;
+import org.apache.asterix.runtime.evaluators.functions.ArrayPrependDescriptor;
+import org.apache.asterix.runtime.evaluators.functions.ArrayPutDescriptor;
+import org.apache.asterix.runtime.evaluators.functions.ArrayRemoveDescriptor;
import org.apache.asterix.runtime.evaluators.functions.ArrayRepeatDescriptor;
import org.apache.asterix.runtime.evaluators.functions.ArrayReverseDescriptor;
import org.apache.asterix.runtime.evaluators.functions.CastTypeDescriptor;
@@ -376,7 +380,11 @@
FunctionCollection fc = new FunctionCollection();
// array functions
- fc.addGenerated(ArrayAppendDescriptor.FACTORY);
+ fc.add(ArrayRemoveDescriptor.FACTORY);
+ fc.add(ArrayPutDescriptor.FACTORY);
+ fc.add(ArrayPrependDescriptor.FACTORY);
+ fc.add(ArrayAppendDescriptor.FACTORY);
+ fc.add(ArrayInsertDescriptor.FACTORY);
fc.addGenerated(ArrayPositionDescriptor.FACTORY);
fc.addGenerated(ArrayRepeatDescriptor.FACTORY);
fc.addGenerated(ArrayReverseDescriptor.FACTORY);
--
To view, visit https://asterix-gerrit.ics.uci.edu/2751
To unsubscribe, visit https://asterix-gerrit.ics.uci.edu/settings
Gerrit-MessageType: newchange
Gerrit-Change-Id: I7d9cb80325138daf99fb039793446d109481c94b
Gerrit-PatchSet: 1
Gerrit-Project: asterixdb
Gerrit-Branch: master
Gerrit-Owner: Ali Alsuliman <[email protected]>