[ASTERIXDB-2562][FUN] Add support for bitwise functions
- user model changes: yes
Added AND, OR, XOR, NOT, SET, CLEAR, SHIFT, TEST, ISSET
and COUNT bitwise functions.
- storage format changes: no
- interface changes: no
Details:
- Introduced the AND, OR, XOR, NOT, SET, CLEAR, SHIFT, TEST, ISSET
and COUNT bitwise functions.
- Added test cases.
Change-Id: I70a6376d6ca12da55eeff88fa0b1c85f970ef8e6
Reviewed-on: https://asterix-gerrit.ics.uci.edu/3377
Contrib: Jenkins <jenkins@fulliautomatix.ics.uci.edu>
Tested-by: Jenkins <jenkins@fulliautomatix.ics.uci.edu>
Integration-Tests: Jenkins <jenkins@fulliautomatix.ics.uci.edu>
Reviewed-by: Dmitry Lychagin <dmitry.lychagin@couchbase.com>
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/bitwise/bit_and_01/bit_and_01.1.query.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/bitwise/bit_and_01/bit_and_01.1.query.sqlpp
new file mode 100644
index 0000000..8d1738c
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/bitwise/bit_and_01/bit_and_01.1.query.sqlpp
@@ -0,0 +1,25 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+{
+"f1": (SELECT value BITAND(3, 6))[0],
+"f2": (SELECT value BITAND(4.0,3))[0],
+"f3": (SELECT value BITAND(3,6,15))[0],
+"f4": (SELECT value BITAND(int8("3"), float("6"), double("15")))[0]
+};
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/bitwise/bit_and_02/bit_and_02.1.query.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/bitwise/bit_and_02/bit_and_02.1.query.sqlpp
new file mode 100644
index 0000000..c5eeab0
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/bitwise/bit_and_02/bit_and_02.1.query.sqlpp
@@ -0,0 +1,29 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+{
+"f1": (SELECT value BITAND(missing, 6))[0] is missing,
+"f2": (SELECT value BITAND(null, 3))[0] is null,
+"f3": (SELECT value BITAND(3, 6, 4.2))[0] is null,
+"f4": (SELECT value BITAND(3, 6, "string"))[0] is null,
+"f5": (SELECT value BITAND(float("INF"), 3, 4))[0] is null,
+"f6": (SELECT value BITAND(float("-INF"), 3, 4))[0] is null,
+"f7": (SELECT value BITAND(float("NaN"), 3, 4))[0] is null,
+"f8": (SELECT value BITAND(double("NaN"), 3, 4))[0] is null
+};
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/bitwise/bit_and_03/bit_and_03.1.query.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/bitwise/bit_and_03/bit_and_03.1.query.sqlpp
new file mode 100644
index 0000000..e973ee9
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/bitwise/bit_and_03/bit_and_03.1.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.
+ */
+
+{
+"f1": (SELECT value BITAND())[0]
+};
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/bitwise/bit_clear_01/bit_clear_01.1.query.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/bitwise/bit_clear_01/bit_clear_01.1.query.sqlpp
new file mode 100644
index 0000000..d586295
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/bitwise/bit_clear_01/bit_clear_01.1.query.sqlpp
@@ -0,0 +1,25 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+{
+"f1": (SELECT value BITCLEAR(6, 1))[0],
+"f2": (SELECT value BITCLEAR(6, [1, 2]))[0],
+"f3": (SELECT value BITCLEAR(31, [1, 2, 4, 5]))[0],
+"f4": (SELECT value BITCLEAR(int8("31"), [int16("1"), float("2"), double("4"), 5]))[0]
+};
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/bitwise/bit_clear_02/bit_clear_02.1.query.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/bitwise/bit_clear_02/bit_clear_02.1.query.sqlpp
new file mode 100644
index 0000000..7c2ac3d
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/bitwise/bit_clear_02/bit_clear_02.1.query.sqlpp
@@ -0,0 +1,29 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+{
+"f1": (SELECT value BITCLEAR(missing, 6))[0] is missing,
+"f2": (SELECT value BITCLEAR(null, 3))[0] is null,
+"f3": (SELECT value BITCLEAR(3, [6, 4.2]))[0] is null,
+"f4": (SELECT value BITCLEAR(3, [6, "string"]))[0] is null,
+"f5": (SELECT value BITCLEAR("string", [1, 2]))[0] is null,
+"f6": (SELECT value BITCLEAR(3, [1, 65]))[0] is null,
+"f7": (SELECT value BITCLEAR(float("INF"), [1, 65]))[0] is null,
+"f8": (SELECT value BITCLEAR(float("-INF"), [1, 65]))[0] is null
+};
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/bitwise/bit_count_01/bit_count_01.1.query.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/bitwise/bit_count_01/bit_count_01.1.query.sqlpp
new file mode 100644
index 0000000..99a38b9
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/bitwise/bit_count_01/bit_count_01.1.query.sqlpp
@@ -0,0 +1,25 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+{
+"f1": (SELECT value BITCOUNT(3))[0],
+"f2": (SELECT value BITCOUNT(4.0))[0],
+"f3": (SELECT value BITCOUNT(int8("-50")))[0],
+"f4": (SELECT value BITCOUNT(double("123456789")))[0]
+};
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/bitwise/bit_count_02/bit_count_02.1.query.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/bitwise/bit_count_02/bit_count_02.1.query.sqlpp
new file mode 100644
index 0000000..a763d74
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/bitwise/bit_count_02/bit_count_02.1.query.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.
+ */
+
+{
+"f1": (SELECT value BITCOUNT(missing))[0] is missing,
+"f2": (SELECT value BITCOUNT(null))[0] is null,
+"f3": (SELECT value BITCOUNT(4.2))[0] is null,
+"f4": (SELECT value BITCOUNT("string"))[0] is null,
+"f5": (SELECT value BITCOUNT(float("INF")))[0] is null,
+"f6": (SELECT value BITCOUNT(float("-INF")))[0] is null
+};
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/bitwise/bit_not_01/bit_not_01.1.query.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/bitwise/bit_not_01/bit_not_01.1.query.sqlpp
new file mode 100644
index 0000000..4903388
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/bitwise/bit_not_01/bit_not_01.1.query.sqlpp
@@ -0,0 +1,25 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+{
+"f1": (SELECT value BITNOT(3))[0],
+"f2": (SELECT value BITNOT(4.0))[0],
+"f3": (SELECT value BITNOT(int8("3")))[0],
+"f4": (SELECT value BITNOT(double("4.0")))[0]
+};
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/bitwise/bit_not_02/bit_not_02.1.query.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/bitwise/bit_not_02/bit_not_02.1.query.sqlpp
new file mode 100644
index 0000000..37f75f4
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/bitwise/bit_not_02/bit_not_02.1.query.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.
+ */
+
+{
+"f1": (SELECT value BITNOT(missing))[0] is missing,
+"f2": (SELECT value BITNOT(null))[0] is null,
+"f3": (SELECT value BITNOT(4.2))[0] is null,
+"f4": (SELECT value BITNOT("string"))[0] is null,
+"f5": (SELECT value BITNOT(float("INF")))[0] is null,
+"f6": (SELECT value BITNOT(float("-INF")))[0] is null
+};
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/bitwise/bit_or_01/bit_or_01.1.query.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/bitwise/bit_or_01/bit_or_01.1.query.sqlpp
new file mode 100644
index 0000000..79404e3
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/bitwise/bit_or_01/bit_or_01.1.query.sqlpp
@@ -0,0 +1,25 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+{
+"f1": (SELECT value BITOR(3, 6))[0],
+"f2": (SELECT value BITOR(3, -4))[0],
+"f3": (SELECT value BITOR(3, 6, 15))[0],
+"f4": (SELECT value BITOR(int8("3"), float("6"), double("15")))[0]
+};
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/bitwise/bit_or_02/bit_or_02.1.query.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/bitwise/bit_or_02/bit_or_02.1.query.sqlpp
new file mode 100644
index 0000000..afef97f
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/bitwise/bit_or_02/bit_or_02.1.query.sqlpp
@@ -0,0 +1,29 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+{
+"f1": (SELECT value BITOR(missing, 6))[0] is missing,
+"f2": (SELECT value BITOR(null, 3))[0] is null,
+"f3": (SELECT value BITOR(3, 6, 4.2))[0] is null,
+"f4": (SELECT value BITOR(3, 6, "string"))[0] is null,
+"f5": (SELECT value BITOR(float("INF"), 6, 4.2))[0] is null,
+"f6": (SELECT value BITOR(float("-INF"), 6, "string"))[0] is null,
+"f7": (SELECT value BITOR(float("NaN"), 6, "string"))[0] is null,
+"f8": (SELECT value BITOR(double("NaN"), 6, "string"))[0] is null
+};
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/bitwise/bit_or_03/bit_or_03.1.query.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/bitwise/bit_or_03/bit_or_03.1.query.sqlpp
new file mode 100644
index 0000000..a81e7f2
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/bitwise/bit_or_03/bit_or_03.1.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.
+ */
+
+{
+"f1": (SELECT value BITOR())[0]
+};
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/bitwise/bit_set_01/bit_set_01.1.query.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/bitwise/bit_set_01/bit_set_01.1.query.sqlpp
new file mode 100644
index 0000000..09a7385
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/bitwise/bit_set_01/bit_set_01.1.query.sqlpp
@@ -0,0 +1,25 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+{
+"f1": (SELECT value BITSET(6, 1))[0],
+"f2": (SELECT value BITSET(6, [1, 2]))[0],
+"f3": (SELECT value BITSET(6, [1, 4]))[0],
+"f4": (SELECT value BITSET(int8("6"), [int16("1"), double("4")]))[0]
+};
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/bitwise/bit_set_02/bit_set_02.1.query.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/bitwise/bit_set_02/bit_set_02.1.query.sqlpp
new file mode 100644
index 0000000..c853266
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/bitwise/bit_set_02/bit_set_02.1.query.sqlpp
@@ -0,0 +1,29 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+{
+"f1": (SELECT value BITSET(missing, 6))[0] is missing,
+"f2": (SELECT value BITSET(null, 3))[0] is null,
+"f3": (SELECT value BITSET(3, [6, 4.2]))[0] is null,
+"f4": (SELECT value BITSET(3, [6, "string"]))[0] is null,
+"f5": (SELECT value BITSET("string", [1, 2]))[0] is null,
+"f6": (SELECT value BITSET(3, [1, 65]))[0] is null,
+"f7": (SELECT value BITSET(float("INF"), [1, 2]))[0] is null,
+"f8": (SELECT value BITSET(float("-INF"), [1, 65]))[0] is null
+};
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/bitwise/bit_shift_01/bit_shift_01.1.query.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/bitwise/bit_shift_01/bit_shift_01.1.query.sqlpp
new file mode 100644
index 0000000..59e8449
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/bitwise/bit_shift_01/bit_shift_01.1.query.sqlpp
@@ -0,0 +1,28 @@
+/*
+ * 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.
+ */
+
+{
+"f1": (SELECT value BITSHIFT(6, 1, FALSE))[0],
+"f2": (SELECT value BITSHIFT(6, -2))[0],
+"f3": (SELECT value BITSHIFT(6, -2, TRUE))[0],
+"f4": (SELECT value BITSHIFT(524288, 45, TRUE))[0],
+"f5": (SELECT value BITSHIFT(int32("524288"), double("45"), TRUE))[0],
+"f6": (SELECT value BITSHIFT(6, 200, true))[0],
+"f7": (SELECT value BITSHIFT(6, -200, true))[0]
+};
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/bitwise/bit_shift_02/bit_shift_02.1.query.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/bitwise/bit_shift_02/bit_shift_02.1.query.sqlpp
new file mode 100644
index 0000000..f58044b
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/bitwise/bit_shift_02/bit_shift_02.1.query.sqlpp
@@ -0,0 +1,30 @@
+/*
+ * 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.
+ */
+
+{
+"f1": (SELECT value BITSHIFT(missing, 6))[0] is missing,
+"f2": (SELECT value BITSHIFT(null, 3))[0] is null,
+"f3": (SELECT value BITSHIFT(3, [6, 4.2]))[0] is null,
+"f4": (SELECT value BITSHIFT(3, [6, "string"]))[0] is null,
+"f5": (SELECT value BITSHIFT("string", [1, 2]))[0] is null,
+"f6": (SELECT value BITSHIFT(3, [1, 65]))[0] is null,
+"f7": (SELECT value BITSHIFT(3, [1, 2], "string"))[0] is null,
+"f8": (SELECT value BITSHIFT(float("INF"), [1, 65]))[0] is null,
+"f9": (SELECT value BITSHIFT(float("-INF"), [1, 2], "string"))[0] is null
+};
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/bitwise/bit_test_01/bit_test_01.1.query.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/bitwise/bit_test_01/bit_test_01.1.query.sqlpp
new file mode 100644
index 0000000..fd4b92f
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/bitwise/bit_test_01/bit_test_01.1.query.sqlpp
@@ -0,0 +1,26 @@
+/*
+ * 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.
+ */
+
+{
+"f1": (SELECT value BITTEST(6, 1))[0],
+"f2": (SELECT value BITTEST(1, [1, 2], FALSE))[0],
+"f3": (SELECT value BITTEST(6, [2, 3], TRUE))[0],
+"f4": (SELECT value BITTEST(6, [1, 3], TRUE))[0],
+"f5": (SELECT value BITTEST(int8("6"), [int16("1"), double("3")], TRUE))[0]
+};
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/bitwise/bit_test_02/bit_test_02.1.query.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/bitwise/bit_test_02/bit_test_02.1.query.sqlpp
new file mode 100644
index 0000000..0aaa86e
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/bitwise/bit_test_02/bit_test_02.1.query.sqlpp
@@ -0,0 +1,30 @@
+/*
+ * 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.
+ */
+
+{
+"f1": (SELECT value BITTEST(missing, 6))[0] is missing,
+"f2": (SELECT value BITTEST(null, 3))[0] is null,
+"f3": (SELECT value BITTEST(3, [6, 4.2]))[0] is null,
+"f4": (SELECT value BITTEST(3, [6, "string"]))[0] is null,
+"f5": (SELECT value BITTEST("string", [1, 2]))[0] is null,
+"f6": (SELECT value BITTEST(3, [1, 65]))[0] is null,
+"f7": (SELECT value BITTEST(3, [1, 2], "string"))[0] is null,
+"f8": (SELECT value BITTEST(float("INF"), [1, 65]))[0] is null,
+"f9": (SELECT value BITTEST(float("-INF"), [1, 2], "string"))[0] is null
+};
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/bitwise/bit_xor_01/bit_xor_01.1.query.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/bitwise/bit_xor_01/bit_xor_01.1.query.sqlpp
new file mode 100644
index 0000000..cf1e9c4
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/bitwise/bit_xor_01/bit_xor_01.1.query.sqlpp
@@ -0,0 +1,25 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+{
+"f1": (SELECT value BITXOR(3, 6))[0],
+"f2": (SELECT value BITXOR(4.0, 3))[0],
+"f3": (SELECT value BITXOR(3, 6, 15))[0],
+"f4": (SELECT value BITXOR(int8("3"), float("6"), double("15")))[0]
+};
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/bitwise/bit_xor_02/bit_xor_02.1.query.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/bitwise/bit_xor_02/bit_xor_02.1.query.sqlpp
new file mode 100644
index 0000000..70e515e
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/bitwise/bit_xor_02/bit_xor_02.1.query.sqlpp
@@ -0,0 +1,29 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+{
+"f1": (SELECT value BITXOR(missing, 6))[0] is missing,
+"f2": (SELECT value BITXOR(null, 3))[0] is null,
+"f3": (SELECT value BITXOR(3, 6, 4.2))[0] is null,
+"f4": (SELECT value BITXOR(3, 6, "string"))[0] is null,
+"f5": (SELECT value BITXOR(float("INF"), 6, 4.2))[0] is null,
+"f6": (SELECT value BITXOR(float("-INF"), 6, "string"))[0] is null,
+"f7": (SELECT value BITXOR(float("NaN"), 6, "string"))[0] is null,
+"f8": (SELECT value BITXOR(double("NaN"), 6, "string"))[0] is null
+};
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/bitwise/bit_xor_03/bit_xor_03.1.query.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/bitwise/bit_xor_03/bit_xor_03.1.query.sqlpp
new file mode 100644
index 0000000..e530c16
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/bitwise/bit_xor_03/bit_xor_03.1.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.
+ */
+
+{
+"f1": (SELECT value BITXOR())[0]
+};
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/bitwise/is_bit_set_01/is_bit_set_01.1.query.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/bitwise/is_bit_set_01/is_bit_set_01.1.query.sqlpp
new file mode 100644
index 0000000..25998c4
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/bitwise/is_bit_set_01/is_bit_set_01.1.query.sqlpp
@@ -0,0 +1,26 @@
+/*
+ * 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.
+ */
+
+{
+"f1": (SELECT value ISBITSET(6, 1))[0],
+"f2": (SELECT value ISBITSET(1, [1, 2], FALSE))[0],
+"f3": (SELECT value ISBITSET(6, [2, 3], TRUE))[0],
+"f4": (SELECT value ISBITSET(6, [1, 3], TRUE))[0],
+"f5": (SELECT value ISBITSET(int("6"), [int8("1"), double("3")], TRUE))[0]
+};
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/bitwise/is_bit_set_02/is_bit_set_02.1.query.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/bitwise/is_bit_set_02/is_bit_set_02.1.query.sqlpp
new file mode 100644
index 0000000..12b8071
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/bitwise/is_bit_set_02/is_bit_set_02.1.query.sqlpp
@@ -0,0 +1,30 @@
+/*
+ * 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.
+ */
+
+{
+"f1": (SELECT value ISBITSET(missing, 6))[0] is missing,
+"f2": (SELECT value ISBITSET(null, 3))[0] is null,
+"f3": (SELECT value ISBITSET(3, [6, 4.2]))[0] is null,
+"f4": (SELECT value ISBITSET(3, [6, "string"]))[0] is null,
+"f5": (SELECT value ISBITSET("string", [1, 2]))[0] is null,
+"f6": (SELECT value ISBITSET(3, [1, 65]))[0] is null,
+"f7": (SELECT value ISBITSET(3, [1, 2], "string"))[0] is null,
+"f8": (SELECT value ISBITSET(float("INF"), [1, 65]))[0] is null,
+"f9": (SELECT value ISBITSET(float("-INF"), [1, 2], "string"))[0] is null
+};
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/results/bitwise/bit_and_01/bit_and_01.1.adm b/asterixdb/asterix-app/src/test/resources/runtimets/results/bitwise/bit_and_01/bit_and_01.1.adm
new file mode 100644
index 0000000..9e3b6df7
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/results/bitwise/bit_and_01/bit_and_01.1.adm
@@ -0,0 +1 @@
+{ "f1": 2, "f2": 0, "f3": 2, "f4": 2 }
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/results/bitwise/bit_and_02/bit_and_02.1.adm b/asterixdb/asterix-app/src/test/resources/runtimets/results/bitwise/bit_and_02/bit_and_02.1.adm
new file mode 100644
index 0000000..f80e8cd
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/results/bitwise/bit_and_02/bit_and_02.1.adm
@@ -0,0 +1 @@
+{ "f1": true, "f2": true, "f3": true, "f4": true, "f5": true, "f6": true, "f7": true, "f8": true }
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/results/bitwise/bit_clear_01/bit_clear_01.1.adm b/asterixdb/asterix-app/src/test/resources/runtimets/results/bitwise/bit_clear_01/bit_clear_01.1.adm
new file mode 100644
index 0000000..ffdb772
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/results/bitwise/bit_clear_01/bit_clear_01.1.adm
@@ -0,0 +1 @@
+{ "f1": 6, "f2": 4, "f3": 4, "f4": 4 }
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/results/bitwise/bit_clear_02/bit_clear_02.1.adm b/asterixdb/asterix-app/src/test/resources/runtimets/results/bitwise/bit_clear_02/bit_clear_02.1.adm
new file mode 100644
index 0000000..f80e8cd
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/results/bitwise/bit_clear_02/bit_clear_02.1.adm
@@ -0,0 +1 @@
+{ "f1": true, "f2": true, "f3": true, "f4": true, "f5": true, "f6": true, "f7": true, "f8": true }
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/results/bitwise/bit_count_01/bit_count_01.1.adm b/asterixdb/asterix-app/src/test/resources/runtimets/results/bitwise/bit_count_01/bit_count_01.1.adm
new file mode 100644
index 0000000..bfe9bd7
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/results/bitwise/bit_count_01/bit_count_01.1.adm
@@ -0,0 +1 @@
+{ "f1": 2, "f2": 1, "f3": 61, "f4": 16 }
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/results/bitwise/bit_count_02/bit_count_02.1.adm b/asterixdb/asterix-app/src/test/resources/runtimets/results/bitwise/bit_count_02/bit_count_02.1.adm
new file mode 100644
index 0000000..8f6cb1f
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/results/bitwise/bit_count_02/bit_count_02.1.adm
@@ -0,0 +1 @@
+{ "f1": true, "f2": true, "f3": true, "f4": true, "f5": true, "f6": true }
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/results/bitwise/bit_not_01/bit_not_01.1.adm b/asterixdb/asterix-app/src/test/resources/runtimets/results/bitwise/bit_not_01/bit_not_01.1.adm
new file mode 100644
index 0000000..4d3a9c2
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/results/bitwise/bit_not_01/bit_not_01.1.adm
@@ -0,0 +1 @@
+{ "f1": -4, "f2": -5, "f3": -4, "f4": -5 }
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/results/bitwise/bit_not_02/bit_not_02.1.adm b/asterixdb/asterix-app/src/test/resources/runtimets/results/bitwise/bit_not_02/bit_not_02.1.adm
new file mode 100644
index 0000000..8f6cb1f
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/results/bitwise/bit_not_02/bit_not_02.1.adm
@@ -0,0 +1 @@
+{ "f1": true, "f2": true, "f3": true, "f4": true, "f5": true, "f6": true }
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/results/bitwise/bit_or_01/bit_or_01.1.adm b/asterixdb/asterix-app/src/test/resources/runtimets/results/bitwise/bit_or_01/bit_or_01.1.adm
new file mode 100644
index 0000000..c50b69b
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/results/bitwise/bit_or_01/bit_or_01.1.adm
@@ -0,0 +1 @@
+{ "f1": 7, "f2": -1, "f3": 15, "f4": 15 }
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/results/bitwise/bit_or_02/bit_or_02.1.adm b/asterixdb/asterix-app/src/test/resources/runtimets/results/bitwise/bit_or_02/bit_or_02.1.adm
new file mode 100644
index 0000000..f80e8cd
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/results/bitwise/bit_or_02/bit_or_02.1.adm
@@ -0,0 +1 @@
+{ "f1": true, "f2": true, "f3": true, "f4": true, "f5": true, "f6": true, "f7": true, "f8": true }
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/results/bitwise/bit_set_01/bit_set_01.1.adm b/asterixdb/asterix-app/src/test/resources/runtimets/results/bitwise/bit_set_01/bit_set_01.1.adm
new file mode 100644
index 0000000..8f27644
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/results/bitwise/bit_set_01/bit_set_01.1.adm
@@ -0,0 +1 @@
+{ "f1": 7, "f2": 7, "f3": 15, "f4": 15 }
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/results/bitwise/bit_set_02/bit_set_02.1.adm b/asterixdb/asterix-app/src/test/resources/runtimets/results/bitwise/bit_set_02/bit_set_02.1.adm
new file mode 100644
index 0000000..f80e8cd
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/results/bitwise/bit_set_02/bit_set_02.1.adm
@@ -0,0 +1 @@
+{ "f1": true, "f2": true, "f3": true, "f4": true, "f5": true, "f6": true, "f7": true, "f8": true }
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/results/bitwise/bit_shift_01/bit_shift_01.1.adm b/asterixdb/asterix-app/src/test/resources/runtimets/results/bitwise/bit_shift_01/bit_shift_01.1.adm
new file mode 100644
index 0000000..a20cddc
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/results/bitwise/bit_shift_01/bit_shift_01.1.adm
@@ -0,0 +1 @@
+{ "f1": 12, "f2": 1, "f3": -9223372036854775807, "f4": 1, "f5": 1, "f6": 1536, "f7": 432345564227567616 }
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/results/bitwise/bit_shift_02/bit_shift_02.1.adm b/asterixdb/asterix-app/src/test/resources/runtimets/results/bitwise/bit_shift_02/bit_shift_02.1.adm
new file mode 100644
index 0000000..d2fd046
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/results/bitwise/bit_shift_02/bit_shift_02.1.adm
@@ -0,0 +1 @@
+{ "f1": true, "f2": true, "f3": true, "f4": true, "f5": true, "f6": true, "f7": true, "f8": true, "f9": true }
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/results/bitwise/bit_test_01/bit_test_01.1.adm b/asterixdb/asterix-app/src/test/resources/runtimets/results/bitwise/bit_test_01/bit_test_01.1.adm
new file mode 100644
index 0000000..23d4ce3
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/results/bitwise/bit_test_01/bit_test_01.1.adm
@@ -0,0 +1 @@
+{ "f1": false, "f2": true, "f3": true, "f4": false, "f5": false }
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/results/bitwise/bit_test_02/bit_test_02.1.adm b/asterixdb/asterix-app/src/test/resources/runtimets/results/bitwise/bit_test_02/bit_test_02.1.adm
new file mode 100644
index 0000000..d2fd046
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/results/bitwise/bit_test_02/bit_test_02.1.adm
@@ -0,0 +1 @@
+{ "f1": true, "f2": true, "f3": true, "f4": true, "f5": true, "f6": true, "f7": true, "f8": true, "f9": true }
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/results/bitwise/bit_xor_01/bit_xor_01.1.adm b/asterixdb/asterix-app/src/test/resources/runtimets/results/bitwise/bit_xor_01/bit_xor_01.1.adm
new file mode 100644
index 0000000..8364ef2
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/results/bitwise/bit_xor_01/bit_xor_01.1.adm
@@ -0,0 +1 @@
+{ "f1": 5, "f2": 7, "f3": 10, "f4": 10 }
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/results/bitwise/bit_xor_02/bit_xor_02.1.adm b/asterixdb/asterix-app/src/test/resources/runtimets/results/bitwise/bit_xor_02/bit_xor_02.1.adm
new file mode 100644
index 0000000..f80e8cd
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/results/bitwise/bit_xor_02/bit_xor_02.1.adm
@@ -0,0 +1 @@
+{ "f1": true, "f2": true, "f3": true, "f4": true, "f5": true, "f6": true, "f7": true, "f8": true }
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/results/bitwise/is_bit_set_01/is_bit_set_01.1.adm b/asterixdb/asterix-app/src/test/resources/runtimets/results/bitwise/is_bit_set_01/is_bit_set_01.1.adm
new file mode 100644
index 0000000..23d4ce3
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/results/bitwise/is_bit_set_01/is_bit_set_01.1.adm
@@ -0,0 +1 @@
+{ "f1": false, "f2": true, "f3": true, "f4": false, "f5": false }
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/results/bitwise/is_bit_set_02/is_bit_set_02.1.adm b/asterixdb/asterix-app/src/test/resources/runtimets/results/bitwise/is_bit_set_02/is_bit_set_02.1.adm
new file mode 100644
index 0000000..d2fd046
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/results/bitwise/is_bit_set_02/is_bit_set_02.1.adm
@@ -0,0 +1 @@
+{ "f1": true, "f2": true, "f3": true, "f4": true, "f5": true, "f6": true, "f7": true, "f8": true, "f9": true }
\ No newline at end of file
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 3ea99ee..1d21dfa 100644
--- a/asterixdb/asterix-app/src/test/resources/runtimets/testsuite_sqlpp.xml
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/testsuite_sqlpp.xml
@@ -2804,6 +2804,126 @@
</compilation-unit>
</test-case>
</test-group>
+ <test-group name="bitwise">
+ <test-case FilePath="bitwise">
+ <compilation-unit name="bit_and_01">
+ <output-dir compare="Text">bit_and_01</output-dir>
+ </compilation-unit>
+ </test-case>
+ <test-case FilePath="bitwise">
+ <compilation-unit name="bit_and_02">
+ <output-dir compare="Text">bit_and_02</output-dir>
+ </compilation-unit>
+ </test-case>
+ <test-case FilePath="bitwise">
+ <compilation-unit name="bit_and_03">
+ <output-dir compare="Text">bit_and_03</output-dir>
+ <expected-error>Invalid number of arguments for function</expected-error>
+ </compilation-unit>
+ </test-case>
+ <test-case FilePath="bitwise">
+ <compilation-unit name="bit_or_01">
+ <output-dir compare="Text">bit_or_01</output-dir>
+ </compilation-unit>
+ </test-case>
+ <test-case FilePath="bitwise">
+ <compilation-unit name="bit_or_02">
+ <output-dir compare="Text">bit_or_02</output-dir>
+ </compilation-unit>
+ </test-case>
+ <test-case FilePath="bitwise">
+ <compilation-unit name="bit_or_03">
+ <output-dir compare="Text">bit_or_03</output-dir>
+ <expected-error>Invalid number of arguments for function</expected-error>
+ </compilation-unit>
+ </test-case>
+ <test-case FilePath="bitwise">
+ <compilation-unit name="bit_xor_01">
+ <output-dir compare="Text">bit_xor_01</output-dir>
+ </compilation-unit>
+ </test-case>
+ <test-case FilePath="bitwise">
+ <compilation-unit name="bit_xor_02">
+ <output-dir compare="Text">bit_xor_02</output-dir>
+ </compilation-unit>
+ </test-case>
+ <test-case FilePath="bitwise">
+ <compilation-unit name="bit_xor_03">
+ <output-dir compare="Text">bit_xor_03</output-dir>
+ <expected-error>Invalid number of arguments for function</expected-error>
+ </compilation-unit>
+ </test-case>
+ <test-case FilePath="bitwise">
+ <compilation-unit name="bit_not_01">
+ <output-dir compare="Text">bit_not_01</output-dir>
+ </compilation-unit>
+ </test-case>
+ <test-case FilePath="bitwise">
+ <compilation-unit name="bit_not_02">
+ <output-dir compare="Text">bit_not_02</output-dir>
+ </compilation-unit>
+ </test-case>
+ <test-case FilePath="bitwise">
+ <compilation-unit name="bit_count_01">
+ <output-dir compare="Text">bit_count_01</output-dir>
+ </compilation-unit>
+ </test-case>
+ <test-case FilePath="bitwise">
+ <compilation-unit name="bit_count_02">
+ <output-dir compare="Text">bit_count_02</output-dir>
+ </compilation-unit>
+ </test-case>
+ <test-case FilePath="bitwise">
+ <compilation-unit name="bit_set_01">
+ <output-dir compare="Text">bit_set_01</output-dir>
+ </compilation-unit>
+ </test-case>
+ <test-case FilePath="bitwise">
+ <compilation-unit name="bit_set_02">
+ <output-dir compare="Text">bit_set_02</output-dir>
+ </compilation-unit>
+ </test-case>
+ <test-case FilePath="bitwise">
+ <compilation-unit name="bit_clear_01">
+ <output-dir compare="Text">bit_clear_01</output-dir>
+ </compilation-unit>
+ </test-case>
+ <test-case FilePath="bitwise">
+ <compilation-unit name="bit_clear_02">
+ <output-dir compare="Text">bit_clear_02</output-dir>
+ </compilation-unit>
+ </test-case>
+ <test-case FilePath="bitwise">
+ <compilation-unit name="bit_shift_01">
+ <output-dir compare="Text">bit_shift_01</output-dir>
+ </compilation-unit>
+ </test-case>
+ <test-case FilePath="bitwise">
+ <compilation-unit name="bit_shift_02">
+ <output-dir compare="Text">bit_shift_02</output-dir>
+ </compilation-unit>
+ </test-case>
+ <test-case FilePath="bitwise">
+ <compilation-unit name="bit_test_01">
+ <output-dir compare="Text">bit_test_01</output-dir>
+ </compilation-unit>
+ </test-case>
+ <test-case FilePath="bitwise">
+ <compilation-unit name="bit_test_02">
+ <output-dir compare="Text">bit_test_02</output-dir>
+ </compilation-unit>
+ </test-case>
+ <test-case FilePath="bitwise">
+ <compilation-unit name="is_bit_set_01">
+ <output-dir compare="Text">is_bit_set_01</output-dir>
+ </compilation-unit>
+ </test-case>
+ <test-case FilePath="bitwise">
+ <compilation-unit name="is_bit_set_02">
+ <output-dir compare="Text">is_bit_set_02</output-dir>
+ </compilation-unit>
+ </test-case>
+ </test-group>
<test-group name="boolean">
<test-case FilePath="boolean">
<compilation-unit name="and_01">
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 d69b6f1..b5105b4 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
@@ -67,6 +67,8 @@
import org.apache.asterix.om.typecomputer.impl.ArrayIfNullTypeComputer;
import org.apache.asterix.om.typecomputer.impl.ArrayRangeTypeComputer;
import org.apache.asterix.om.typecomputer.impl.ArrayRepeatTypeComputer;
+import org.apache.asterix.om.typecomputer.impl.BitMultipleValuesTypeComputer;
+import org.apache.asterix.om.typecomputer.impl.BitValuePositionFlagTypeComputer;
import org.apache.asterix.om.typecomputer.impl.BooleanFunctionTypeComputer;
import org.apache.asterix.om.typecomputer.impl.BooleanOnlyTypeComputer;
import org.apache.asterix.om.typecomputer.impl.BooleanOrMissingTypeComputer;
@@ -381,6 +383,32 @@
public static final FunctionIdentifier FIND_BINARY_FROM =
new FunctionIdentifier(FunctionConstants.ASTERIX_NS, "find-binary", 3);
+ // bitwise functions
+ public static final FunctionIdentifier BIT_AND =
+ new FunctionIdentifier(FunctionConstants.ASTERIX_NS, "bitand", FunctionIdentifier.VARARGS);
+ public static final FunctionIdentifier BIT_OR =
+ new FunctionIdentifier(FunctionConstants.ASTERIX_NS, "bitor", FunctionIdentifier.VARARGS);
+ public static final FunctionIdentifier BIT_XOR =
+ new FunctionIdentifier(FunctionConstants.ASTERIX_NS, "bitxor", FunctionIdentifier.VARARGS);
+ public static final FunctionIdentifier BIT_NOT = new FunctionIdentifier(FunctionConstants.ASTERIX_NS, "bitnot", 1);
+ public static final FunctionIdentifier BIT_COUNT =
+ new FunctionIdentifier(FunctionConstants.ASTERIX_NS, "bitcount", 1);
+ public static final FunctionIdentifier BIT_SET = new FunctionIdentifier(FunctionConstants.ASTERIX_NS, "bitset", 2);
+ public static final FunctionIdentifier BIT_CLEAR =
+ new FunctionIdentifier(FunctionConstants.ASTERIX_NS, "bitclear", 2);
+ public static final FunctionIdentifier BIT_SHIFT_WITHOUT_ROTATE_FLAG =
+ new FunctionIdentifier(FunctionConstants.ASTERIX_NS, "bitshift", 2);
+ public static final FunctionIdentifier BIT_SHIFT_WITH_ROTATE_FLAG =
+ new FunctionIdentifier(FunctionConstants.ASTERIX_NS, "bitshift", 3);
+ public static final FunctionIdentifier BIT_TEST_WITHOUT_ALL_FLAG =
+ new FunctionIdentifier(FunctionConstants.ASTERIX_NS, "bittest", 2);
+ public static final FunctionIdentifier BIT_TEST_WITH_ALL_FLAG =
+ new FunctionIdentifier(FunctionConstants.ASTERIX_NS, "bittest", 3);
+ public static final FunctionIdentifier IS_BIT_SET_WITHOUT_ALL_FLAG =
+ new FunctionIdentifier(FunctionConstants.ASTERIX_NS, "isbitset", 2);
+ public static final FunctionIdentifier IS_BIT_SET_WITH_ALL_FLAG =
+ new FunctionIdentifier(FunctionConstants.ASTERIX_NS, "isbitset", 3);
+
// String functions
public static final FunctionIdentifier STRING_EQUAL =
new FunctionIdentifier(FunctionConstants.ASTERIX_NS, "string-equal", 2);
@@ -1683,6 +1711,20 @@
addFunction(FIND_BINARY, AInt64TypeComputer.INSTANCE, true);
addFunction(FIND_BINARY_FROM, AInt64TypeComputer.INSTANCE, true);
+ addFunction(BIT_AND, BitMultipleValuesTypeComputer.INSTANCE_INT64, true);
+ addFunction(BIT_OR, BitMultipleValuesTypeComputer.INSTANCE_INT64, true);
+ addFunction(BIT_XOR, BitMultipleValuesTypeComputer.INSTANCE_INT64, true);
+ addFunction(BIT_NOT, BitMultipleValuesTypeComputer.INSTANCE_INT64, true);
+ addFunction(BIT_COUNT, BitMultipleValuesTypeComputer.INSTANCE_INT32, true);
+ addFunction(BIT_SET, BitValuePositionFlagTypeComputer.INSTANCE_SET_CLEAR, true);
+ addFunction(BIT_CLEAR, BitValuePositionFlagTypeComputer.INSTANCE_SET_CLEAR, true);
+ addFunction(BIT_SHIFT_WITHOUT_ROTATE_FLAG, BitValuePositionFlagTypeComputer.INSTANCE_SHIFT_WITHOUT_FLAG, true);
+ addFunction(BIT_SHIFT_WITH_ROTATE_FLAG, BitValuePositionFlagTypeComputer.INSTANCE_SHIFT_WITH_FLAG, true);
+ addFunction(BIT_TEST_WITHOUT_ALL_FLAG, BitValuePositionFlagTypeComputer.INSTANCE_TEST_WITHOUT_FLAG, true);
+ addFunction(BIT_TEST_WITH_ALL_FLAG, BitValuePositionFlagTypeComputer.INSTANCE_TEST_WITH_FLAG, true);
+ addFunction(IS_BIT_SET_WITHOUT_ALL_FLAG, BitValuePositionFlagTypeComputer.INSTANCE_TEST_WITHOUT_FLAG, true);
+ addFunction(IS_BIT_SET_WITH_ALL_FLAG, BitValuePositionFlagTypeComputer.INSTANCE_TEST_WITH_FLAG, true);
+
addFunction(STRING_CONSTRUCTOR, AStringTypeComputer.INSTANCE, true);
addFunction(STRING_LIKE, BooleanFunctionTypeComputer.INSTANCE, true);
addFunction(STRING_CONTAINS, ABooleanTypeComputer.INSTANCE, true);
diff --git a/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/typecomputer/impl/BitMultipleValuesTypeComputer.java b/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/typecomputer/impl/BitMultipleValuesTypeComputer.java
new file mode 100644
index 0000000..3117fba
--- /dev/null
+++ b/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/typecomputer/impl/BitMultipleValuesTypeComputer.java
@@ -0,0 +1,89 @@
+/*
+ * 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.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;
+import org.apache.hyracks.algebricks.core.algebra.base.ILogicalExpression;
+import org.apache.hyracks.algebricks.core.algebra.expressions.AbstractFunctionCallExpression;
+
+/**
+ * This type computer expects one or more arguments. The return type is int32 or int64 depending on the function used.
+ *
+ * The behavior of this type computer is as follows:
+ * - If the argument is missing or null, then missing or null is returned, respectively.
+ * - If the argument is int64, then int32 or int64 is returned.
+ * - If the argument is float or double, then int32, int64 or null is returned, depending on the argument value.
+ * - If the argument is any other type, then null is returned.
+ */
+
+public class BitMultipleValuesTypeComputer extends AbstractResultTypeComputer {
+
+ public static final BitMultipleValuesTypeComputer INSTANCE_INT32 =
+ new BitMultipleValuesTypeComputer(1, BuiltinType.AINT32);
+ public static final BitMultipleValuesTypeComputer INSTANCE_INT64 =
+ new BitMultipleValuesTypeComputer(1, BuiltinType.AINT64);
+
+ private BitMultipleValuesTypeComputer(int minArgs, IAType returnType) {
+ this.minArgs = minArgs;
+ this.returnType = returnType;
+ }
+
+ private final int minArgs;
+ private final IAType returnType;
+
+ @Override
+ protected IAType getResultType(ILogicalExpression expr, IAType... strippedInputTypes) throws AlgebricksException {
+
+ // Ensure minimum arguments are passed
+ if (strippedInputTypes.length < minArgs) {
+ String functionName = ((AbstractFunctionCallExpression) expr).getFunctionIdentifier().getName();
+ throw new CompilationException(ErrorCode.COMPILATION_INVALID_NUM_OF_ARGS, expr.getSourceLocation(),
+ functionName);
+ }
+
+ // Result can be nullable in case of invalid arguments like double value of 4.5 (4.0 is acceptable, 4.5 is not)
+ boolean isReturnNullable = false;
+
+ // Check that all arguments are of valid type, otherwise a null is returned
+ for (IAType type : strippedInputTypes) {
+ switch (type.getTypeTag()) {
+ case TINYINT:
+ case SMALLINT:
+ case INTEGER:
+ case BIGINT:
+ continue;
+ case FLOAT:
+ case DOUBLE:
+ case ANY:
+ isReturnNullable = true;
+ continue;
+ default:
+ return BuiltinType.ANULL;
+ }
+ }
+
+ return isReturnNullable ? AUnionType.createNullableType(returnType) : returnType;
+ }
+}
diff --git a/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/typecomputer/impl/BitValuePositionFlagTypeComputer.java b/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/typecomputer/impl/BitValuePositionFlagTypeComputer.java
new file mode 100644
index 0000000..3e3256a
--- /dev/null
+++ b/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/typecomputer/impl/BitValuePositionFlagTypeComputer.java
@@ -0,0 +1,162 @@
+/*
+ * 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.om.typecomputer.base.AbstractResultTypeComputer;
+import org.apache.asterix.om.types.AOrderedListType;
+import org.apache.asterix.om.types.AUnionType;
+import org.apache.asterix.om.types.BuiltinType;
+import org.apache.asterix.om.types.IAType;
+import org.apache.hyracks.algebricks.common.exceptions.AlgebricksException;
+import org.apache.hyracks.algebricks.core.algebra.base.ILogicalExpression;
+
+/**
+ * This type computer expects 2 or 3 arguments, first argument representing the value, second argument representing
+ * the position(s), and third argument (optional) representing a boolean flag. Each instance contains the type it is
+ * returning, this is referred to as returnType in the below details.
+ *
+ * The behavior of this type computer is as follows:
+ * For the first argument:
+ * - If the argument is missing or null, then missing or null is returned, respectively.
+ * - If the argument is int64, then returnType is returned.
+ * - If the argument is float or double, then returnType or null is returned, depending on the argument value.
+ * - If the argument is any other type, then null is returned.
+ *
+ * For the second argument:
+ * - If the argument is missing or null, then missing or null is returned, respectively.
+ * - If the argument is int64, then returnType is returned.
+ * - If the argument is float or double, then returnType or null is returned, depending on the argument value.
+ * - If the position argument is an array:
+ * - If the array item is missing or null, then missing or null is returned, respectively.
+ * - If the array item is int64, then returnType is returned.
+ * - If the array item is float or double, then returnType or null is returned, depending on the argument value.
+ * - If the array item is any other type, then null is returned.
+ * - If the argument is any other type, then null is returned.
+ *
+ * For the third argument (if provided):
+ * - If the argument is missing or null, then missing or null is returned, respectively.
+ * - If the argument is of type boolean, then returnType is returned.
+ * - If the argument is any other type, then null is returned.
+ */
+
+public class BitValuePositionFlagTypeComputer extends AbstractResultTypeComputer {
+
+ public static final BitValuePositionFlagTypeComputer INSTANCE_SET_CLEAR =
+ new BitValuePositionFlagTypeComputer(2, true, BuiltinType.AINT64);
+ public static final BitValuePositionFlagTypeComputer INSTANCE_SHIFT_WITH_FLAG =
+ new BitValuePositionFlagTypeComputer(2, false, BuiltinType.AINT64);
+ public static final BitValuePositionFlagTypeComputer INSTANCE_SHIFT_WITHOUT_FLAG =
+ new BitValuePositionFlagTypeComputer(3, false, BuiltinType.AINT64);
+ public static final BitValuePositionFlagTypeComputer INSTANCE_TEST_WITH_FLAG =
+ new BitValuePositionFlagTypeComputer(2, true, BuiltinType.ABOOLEAN);
+ public static final BitValuePositionFlagTypeComputer INSTANCE_TEST_WITHOUT_FLAG =
+ new BitValuePositionFlagTypeComputer(3, true, BuiltinType.ABOOLEAN);
+
+ private BitValuePositionFlagTypeComputer(int numberOfArguments, boolean secondArgCanBeArray, IAType returnType) {
+ this.numberOfArguments = numberOfArguments;
+ this.secondArgCanBeArray = secondArgCanBeArray;
+ this.returnType = returnType;
+ }
+
+ private final int numberOfArguments;
+ private final boolean secondArgCanBeArray;
+ private final IAType returnType;
+
+ @Override
+ protected IAType getResultType(ILogicalExpression expr, IAType... strippedInputTypes) throws AlgebricksException {
+
+ // Result can be nullable in case of invalid arguments like double value of 4.5 (4.0 is acceptable, 4.5 is not)
+ boolean isReturnNullable = false;
+
+ IAType firstArgument = strippedInputTypes[0];
+ IAType secondArgument = strippedInputTypes[1];
+
+ // First argument needs to be numeric
+ switch (firstArgument.getTypeTag()) {
+ case TINYINT:
+ case SMALLINT:
+ case INTEGER:
+ case BIGINT:
+ break;
+ case FLOAT:
+ case DOUBLE:
+ case ANY:
+ isReturnNullable = true;
+ break;
+ default:
+ return BuiltinType.ANULL;
+ }
+
+ // Second argument needs to be numeric
+ switch (secondArgument.getTypeTag()) {
+ case TINYINT:
+ case SMALLINT:
+ case INTEGER:
+ case BIGINT:
+ break;
+ case FLOAT:
+ case DOUBLE:
+ case ANY:
+ isReturnNullable = true;
+ break;
+ case ARRAY:
+ if (!secondArgCanBeArray) {
+ return BuiltinType.ANULL;
+ }
+ // In case of array, ensure the validity of array item type
+ AOrderedListType listType = (AOrderedListType) secondArgument;
+ IAType itemType = listType.getItemType();
+
+ switch (itemType.getTypeTag()) {
+ case TINYINT:
+ case SMALLINT:
+ case INTEGER:
+ case BIGINT:
+ break;
+ case FLOAT:
+ case DOUBLE:
+ case ANY:
+ isReturnNullable = true;
+ break;
+ default:
+ return BuiltinType.ANULL;
+ }
+ break;
+ default:
+ return BuiltinType.ANULL;
+ }
+
+ // Third argument needs to be a boolean
+ // The strippedInputTypes.length >= 3 is for some tests to work properly, can be removed when the test is fixed
+ if (numberOfArguments == 3 && strippedInputTypes.length >= 3) {
+ IAType thirdArgument = strippedInputTypes[2];
+ switch (thirdArgument.getTypeTag()) {
+ case BOOLEAN:
+ break;
+ case ANY:
+ isReturnNullable = true;
+ break;
+ default:
+ return BuiltinType.ANULL;
+ }
+ }
+
+ return isReturnNullable ? AUnionType.createNullableType(returnType) : returnType;
+ }
+}
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 8559208..56dd802 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
@@ -22,9 +22,12 @@
import java.io.IOException;
import java.util.Collection;
+import org.apache.asterix.dataflow.data.nontagged.serde.ADoubleSerializerDeserializer;
+import org.apache.asterix.dataflow.data.nontagged.serde.AFloatSerializerDeserializer;
import org.apache.asterix.om.pointables.base.IVisitablePointable;
import org.apache.asterix.om.types.ATypeTag;
import org.apache.asterix.om.types.EnumDeserializer;
+import org.apache.asterix.om.types.hierachy.ATypeHierarchy;
import org.apache.hyracks.api.dataflow.value.IBinaryComparator;
import org.apache.hyracks.api.exceptions.HyracksDataException;
import org.apache.hyracks.data.std.api.IMutableValueStorage;
@@ -276,4 +279,52 @@
return PointableValueState.PRESENT;
}
+
+ /**
+ * Check if the provided bytes are of valid long type. In case floats and doubles are accepted, the accepted
+ * values will be 1.0 and 2.0, but not 2.5. (only zero decimals)
+ *
+ * @param bytes data bytes
+ * @param startOffset start offset
+ * @param acceptFloatAndDouble flag to accept float and double values or not
+ *
+ * @return true if provided value is a valid long, false otherwise
+ */
+ public static boolean isValidLongValue(byte[] bytes, int startOffset, boolean acceptFloatAndDouble) {
+
+ // Type tag
+ ATypeTag typeTag = EnumDeserializer.ATYPETAGDESERIALIZER.deserialize(bytes[startOffset]);
+
+ // If floats and doubles aren't allowed, we only check if it can be int64
+ if (!acceptFloatAndDouble) {
+ return ATypeHierarchy.canPromote(typeTag, ATypeTag.BIGINT);
+ }
+
+ // We accept floats and doubles, do all the checks
+ if (!ATypeHierarchy.canPromote(typeTag, ATypeTag.DOUBLE)) {
+ return false;
+ }
+
+ // Float check (1.0, 2.0 are fine, but 1.5 is not)
+ if (typeTag == ATypeTag.FLOAT) {
+ float value = AFloatSerializerDeserializer.getFloat(bytes, startOffset + 1);
+
+ // Max and min checks, has a decimal value that is not 0
+ if (value > Long.MAX_VALUE || value < Long.MIN_VALUE || value > Math.floor(value) || Float.isNaN(value)) {
+ return false;
+ }
+ }
+
+ // Double check (1.0, 2.0 are fine, but 1.5 is not)
+ if (typeTag == ATypeTag.DOUBLE) {
+ double value = ADoubleSerializerDeserializer.getDouble(bytes, startOffset + 1);
+
+ // Max and min checks, has a decimal value that is not 0
+ if (value > Long.MAX_VALUE || value < Long.MIN_VALUE || value > Math.floor(value) || Double.isNaN(value)) {
+ return false;
+ }
+ }
+
+ return true;
+ }
}
diff --git a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/bitwise/AbstractBitMultipleValuesEvaluator.java b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/bitwise/AbstractBitMultipleValuesEvaluator.java
new file mode 100644
index 0000000..ce03fa5
--- /dev/null
+++ b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/bitwise/AbstractBitMultipleValuesEvaluator.java
@@ -0,0 +1,142 @@
+/*
+ * 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.bitwise;
+
+import org.apache.asterix.formats.nontagged.SerializerDeserializerProvider;
+import org.apache.asterix.om.base.AMutableInt64;
+import org.apache.asterix.om.types.ATypeTag;
+import org.apache.asterix.om.types.BuiltinType;
+import org.apache.asterix.om.types.hierachy.ATypeHierarchy;
+import org.apache.asterix.runtime.evaluators.functions.AbstractScalarEval;
+import org.apache.asterix.runtime.evaluators.functions.PointableHelper;
+import org.apache.hyracks.algebricks.core.algebra.functions.FunctionIdentifier;
+import org.apache.hyracks.algebricks.runtime.base.IScalarEvaluator;
+import org.apache.hyracks.algebricks.runtime.base.IScalarEvaluatorFactory;
+import org.apache.hyracks.api.context.IHyracksTaskContext;
+import org.apache.hyracks.api.dataflow.value.ISerializerDeserializer;
+import org.apache.hyracks.api.exceptions.HyracksDataException;
+import org.apache.hyracks.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;
+
+/**
+ * This function receives one or more arguments, applies the bitwise operation to all of the arguments
+ * and returns the result. This evaluator is used by the Bitwise AND, OR, XOR, ... etc functions.
+ * These functions can be applied only to int64 type numeric values.
+ *
+ * The function has the following behavior:
+ * - If the argument is missing or null, then missing or null is returned, respectively.
+ * - If the argument is int64, then int64 is returned.
+ * - If the argument is float or double, then int64 or null is returned, depending on the argument value.
+ * - If the argument is any other type, then null is returned.
+ */
+
+abstract class AbstractBitMultipleValuesEvaluator extends AbstractScalarEval {
+
+ // Result members
+ private final AMutableInt64 resultMutableInt64 = new AMutableInt64(0);
+ private final ArrayBackedValueStorage resultStorage = new ArrayBackedValueStorage();
+
+ // Evaluators and Pointables
+ private final IScalarEvaluator[] argEvaluators;
+ private final IPointable[] argPointables;
+
+ // Serializer/Deserializer
+ @SuppressWarnings("rawtypes")
+ private final ISerializerDeserializer aInt64Serde =
+ SerializerDeserializerProvider.INSTANCE.getSerializerDeserializer(BuiltinType.AINT64);
+
+ AbstractBitMultipleValuesEvaluator(IHyracksTaskContext context, IScalarEvaluatorFactory[] argEvaluatorFactories,
+ FunctionIdentifier functionIdentifier, SourceLocation sourceLocation) throws HyracksDataException {
+ super(sourceLocation, functionIdentifier);
+
+ // Evaluators and Pointables
+ argPointables = new IPointable[argEvaluatorFactories.length];
+ argEvaluators = new IScalarEvaluator[argEvaluatorFactories.length];
+ for (int i = 0; i < argEvaluatorFactories.length; i++) {
+ argEvaluators[i] = argEvaluatorFactories[i].createScalarEvaluator(context);
+ argPointables[i] = new VoidPointable();
+ }
+ }
+
+ // Abstract methods
+ abstract long applyBitwiseOperation(long value1, long value2);
+
+ @SuppressWarnings("unchecked")
+ @Override
+ public void evaluate(IFrameTupleReference tuple, IPointable result) throws HyracksDataException {
+ boolean isReturnNull = false;
+
+ // Evaluate and check the arguments (Missing/Null checks)
+ for (int i = 0; i < argEvaluators.length; i++) {
+ argEvaluators[i].evaluate(tuple, argPointables[i]);
+
+ if (PointableHelper.checkAndSetMissingOrNull(result, argPointables[i])) {
+ if (result.getByteArray()[result.getStartOffset()] == ATypeTag.SERIALIZED_MISSING_TYPE_TAG) {
+ return;
+ }
+
+ // null value, but check other arguments for missing first (higher priority)
+ isReturnNull = true;
+ }
+ }
+
+ if (isReturnNull) {
+ PointableHelper.setNull(result);
+ return;
+ }
+
+ // First argument
+ byte[] bytes = argPointables[0].getByteArray();
+ int startOffset = argPointables[0].getStartOffset();
+
+ // Type and value validity check
+ if (!PointableHelper.isValidLongValue(bytes, startOffset, true)) {
+ PointableHelper.setNull(result);
+ return;
+ }
+
+ // Result holder
+ long longResult = ATypeHierarchy.getLongValue(functionIdentifier.getName(), 0, bytes, startOffset);
+
+ // Loop and do the bitwise operation for all the arguments (start from index 1, we did first argument above)
+ for (int i = 1; i < argPointables.length; i++) {
+ bytes = argPointables[i].getByteArray();
+ startOffset = argPointables[i].getStartOffset();
+
+ // Type and value validity check
+ if (!PointableHelper.isValidLongValue(bytes, startOffset, true)) {
+ PointableHelper.setNull(result);
+ return;
+ }
+
+ long nextValue = ATypeHierarchy.getLongValue(functionIdentifier.getName(), i, bytes, startOffset);
+ longResult = applyBitwiseOperation(longResult, nextValue);
+ }
+
+ // Write the result
+ resultStorage.reset();
+ resultMutableInt64.setValue(longResult);
+ aInt64Serde.serialize(resultMutableInt64, resultStorage.getDataOutput());
+ result.set(resultStorage);
+ }
+}
diff --git a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/bitwise/AbstractBitSingleValueEvaluator.java b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/bitwise/AbstractBitSingleValueEvaluator.java
new file mode 100644
index 0000000..578e005
--- /dev/null
+++ b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/bitwise/AbstractBitSingleValueEvaluator.java
@@ -0,0 +1,92 @@
+/*
+ * 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.bitwise;
+
+import org.apache.asterix.om.types.hierachy.ATypeHierarchy;
+import org.apache.asterix.runtime.evaluators.functions.AbstractScalarEval;
+import org.apache.asterix.runtime.evaluators.functions.PointableHelper;
+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.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;
+
+/**
+ * This function receives one argument, representing the value. This evaluator is used by the Bitwise NOT and COUNT
+ * functions.
+ * This function can be applied only to int64 type numeric values.
+ *
+ * The function has the following behavior:
+ * - If the argument is missing or null, then missing or null is returned, respectively.
+ * - If the argument is int64, then int32 or int64 is returned, depending on the calling function.
+ * - If the argument is float or double, then int32 or int64 or null is returned, depending on the argument value.
+ * - If the argument is any other type, then null is returned.
+ */
+
+abstract class AbstractBitSingleValueEvaluator extends AbstractScalarEval {
+
+ // Result members
+ final ArrayBackedValueStorage resultStorage = new ArrayBackedValueStorage();
+
+ // Evaluators and Pointables
+ private final IScalarEvaluator valueEvaluator;
+ private final IPointable valuePointable = VoidPointable.FACTORY.createPointable();
+
+ AbstractBitSingleValueEvaluator(IHyracksTaskContext context, IScalarEvaluatorFactory[] argEvaluatorFactories,
+ FunctionIdentifier functionIdentifier, SourceLocation sourceLocation) throws HyracksDataException {
+ super(sourceLocation, functionIdentifier);
+
+ // Evaluator
+ valueEvaluator = argEvaluatorFactories[0].createScalarEvaluator(context);
+ }
+
+ // Abstract methods
+ abstract void applyBitwiseOperation(long value);
+
+ abstract void writeResult(IPointable result) throws HyracksDataException;
+
+ @Override
+ public void evaluate(IFrameTupleReference tuple, IPointable result) throws HyracksDataException {
+
+ valueEvaluator.evaluate(tuple, valuePointable);
+ if (PointableHelper.checkAndSetMissingOrNull(result, valuePointable)) {
+ return;
+ }
+
+ byte[] bytes = valuePointable.getByteArray();
+ int startOffset = valuePointable.getStartOffset();
+
+ // Validity check
+ if (!PointableHelper.isValidLongValue(bytes, startOffset, true)) {
+ PointableHelper.setNull(result);
+ return;
+ }
+
+ long longValue = ATypeHierarchy.getLongValue(functionIdentifier.getName(), 0, bytes, startOffset);
+ applyBitwiseOperation(longValue);
+
+ writeResult(result);
+ }
+}
diff --git a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/bitwise/AbstractBitValuePositionEvaluator.java b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/bitwise/AbstractBitValuePositionEvaluator.java
new file mode 100644
index 0000000..077dbe4
--- /dev/null
+++ b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/bitwise/AbstractBitValuePositionEvaluator.java
@@ -0,0 +1,227 @@
+/*
+ * 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.bitwise;
+
+import java.io.IOException;
+
+import org.apache.asterix.formats.nontagged.SerializerDeserializerProvider;
+import org.apache.asterix.om.base.AMutableInt64;
+import org.apache.asterix.om.types.ATypeTag;
+import org.apache.asterix.om.types.BuiltinType;
+import org.apache.asterix.om.types.EnumDeserializer;
+import org.apache.asterix.om.types.hierachy.ATypeHierarchy;
+import org.apache.asterix.runtime.evaluators.common.ListAccessor;
+import org.apache.asterix.runtime.evaluators.functions.AbstractScalarEval;
+import org.apache.asterix.runtime.evaluators.functions.PointableHelper;
+import org.apache.hyracks.algebricks.core.algebra.functions.FunctionIdentifier;
+import org.apache.hyracks.algebricks.runtime.base.IScalarEvaluator;
+import org.apache.hyracks.algebricks.runtime.base.IScalarEvaluatorFactory;
+import org.apache.hyracks.api.context.IHyracksTaskContext;
+import org.apache.hyracks.api.dataflow.value.ISerializerDeserializer;
+import org.apache.hyracks.api.exceptions.HyracksDataException;
+import org.apache.hyracks.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;
+
+/**
+ * This function receives two arguments, first argument representing the value, and second argument representing
+ * the position to apply the operation at. The position can be a single value or an array of values. This evaluator
+ * is used by the bitwise CLEAR and SET functions.
+ *
+ * These functions can be applied only to int64 type numeric values.
+ *
+ * The function has the following behavior:
+ * For the first argument:
+ * - If the argument is missing or null, then missing or null is returned, respectively.
+ * - If the argument is int64, then int64 is returned.
+ * - If the argument is float or double, then int64 or null is returned, depending on the argument value.
+ * - If the argument is any other type, then null is returned.
+ *
+ * For the second argument:
+ * - If the argument is missing or null, then missing or null is returned, respectively.
+ * - If the argument is int64, then int64 is returned.
+ * - If the argument is float or double, then int64 or null is returned, depending on the argument value.
+ * - If the argument is an array:
+ * - If the array item type is int64, then int64 or boolean is returned.
+ * - If the array item type is float or double, then int64 or null is returned, depending on the argument.
+ * - If the array item type is any other type, then null is returned.
+ * - If the argument is any other type, then null is returned.
+ */
+
+abstract class AbstractBitValuePositionEvaluator extends AbstractScalarEval {
+
+ // Result members
+ private long longResult;
+ private final AMutableInt64 resultMutableInt64 = new AMutableInt64(0);
+ private final ArrayBackedValueStorage resultStorage = new ArrayBackedValueStorage();
+
+ // Evaluators and Pointables
+ private final IScalarEvaluator valueEvaluator;
+ private final IScalarEvaluator positionEvaluator;
+ private final IPointable valuePointable = new VoidPointable();
+ private final IPointable positionPointable = new VoidPointable();
+
+ // List accessor
+ private final ListAccessor listAccessor = new ListAccessor();
+ private final IPointable listItemPointable = new VoidPointable();
+
+ // Serializer/Deserializer
+ @SuppressWarnings("rawtypes")
+ private final ISerializerDeserializer aInt64Serde =
+ SerializerDeserializerProvider.INSTANCE.getSerializerDeserializer(BuiltinType.AINT64);
+
+ AbstractBitValuePositionEvaluator(IHyracksTaskContext context, IScalarEvaluatorFactory[] argEvaluatorFactories,
+ FunctionIdentifier functionIdentifier, SourceLocation sourceLocation) throws HyracksDataException {
+ super(sourceLocation, functionIdentifier);
+
+ // Evaluators
+ valueEvaluator = argEvaluatorFactories[0].createScalarEvaluator(context);
+ positionEvaluator = argEvaluatorFactories[1].createScalarEvaluator(context);
+ }
+
+ // Abstract methods
+ abstract long applyBitwiseOperation(long value, long position);
+
+ @SuppressWarnings("unchecked")
+ @Override
+ public void evaluate(IFrameTupleReference tuple, IPointable result) throws HyracksDataException {
+
+ valueEvaluator.evaluate(tuple, valuePointable);
+ positionEvaluator.evaluate(tuple, positionPointable);
+
+ if (PointableHelper.checkAndSetMissingOrNull(result, valuePointable, positionPointable)) {
+ return;
+ }
+
+ // Value argument
+ byte[] valueBytes = valuePointable.getByteArray();
+ int valueStartOffset = valuePointable.getStartOffset();
+
+ // Type and value validity check
+ if (!PointableHelper.isValidLongValue(valueBytes, valueStartOffset, true)) {
+ PointableHelper.setNull(result);
+ return;
+ }
+
+ // Position argument
+ byte[] positionBytes = positionPointable.getByteArray();
+ int positionStartOffset = positionPointable.getStartOffset();
+ ATypeTag positionTypeTag =
+ EnumDeserializer.ATYPETAGDESERIALIZER.deserialize(positionBytes[positionStartOffset]);
+
+ // Type validity check (for position argument, array is a valid type as well)
+ if (!ATypeHierarchy.canPromote(positionTypeTag, ATypeTag.DOUBLE) && positionTypeTag != ATypeTag.ARRAY) {
+ PointableHelper.setNull(result);
+ return;
+ }
+
+ // Result long value
+ longResult = ATypeHierarchy.getLongValue(functionIdentifier.getName(), 0, valueBytes, valueStartOffset);
+
+ // If any operation returns false, the result should be null
+ boolean isSuccessfulOperation;
+
+ // From here onward, we got valid arguments, so let's handle numeric or array position argument
+ if (positionTypeTag != ATypeTag.ARRAY) {
+ isSuccessfulOperation = applyBitWiseOperationWithNumericAsPosition(positionBytes, positionStartOffset);
+ } else {
+ isSuccessfulOperation = applyBitWiseOperationWithArrayAsPosition(positionBytes, positionStartOffset);
+ }
+
+ if (!isSuccessfulOperation) {
+ PointableHelper.setNull(result);
+ return;
+ }
+
+ // Write the result
+ resultStorage.reset();
+ resultMutableInt64.setValue(longResult);
+ aInt64Serde.serialize(resultMutableInt64, resultStorage.getDataOutput());
+ result.set(resultStorage);
+ }
+
+ /**
+ * This method applies the bitwise operation on the value at the specified positions in the array.
+ *
+ * @param bytes bytes of the position
+ * @param startOffset start offset of the position
+ * @return returns {@code true} if all operations are successful, {@code false} otherwise.
+ *
+ * @throws HyracksDataException HyracksDataException
+ */
+ private boolean applyBitWiseOperationWithArrayAsPosition(byte[] bytes, int startOffset)
+ throws HyracksDataException {
+
+ listAccessor.reset(bytes, startOffset);
+
+ // In case of an empty array, we return the value as is without change
+ if (listAccessor.size() == 0) {
+ return true;
+ }
+
+ try {
+ // For each item in the array, apply the bitwise operation at that position
+ for (int i = 0; i < listAccessor.size(); i++) {
+ resultStorage.reset();
+ listAccessor.getOrWriteItem(i, listItemPointable, resultStorage);
+
+ byte[] itemBytes = listItemPointable.getByteArray();
+ int itemStartOffset = listItemPointable.getStartOffset();
+
+ if (!applyBitWiseOperationWithNumericAsPosition(itemBytes, itemStartOffset)) {
+ return false;
+ }
+ }
+
+ return true;
+ } catch (IOException ex) {
+ throw HyracksDataException.create(ex);
+ }
+ }
+
+ /**
+ * This method applies the bitwise operation on the value at the specified position.
+ *
+ * @param bytes data bytes
+ * @param startOffset start offset
+ * @return returns {@code true} if all operations are successful, {@code false} otherwise.
+ */
+ private boolean applyBitWiseOperationWithNumericAsPosition(byte[] bytes, int startOffset)
+ throws HyracksDataException {
+
+ // Value validity check
+ if (!PointableHelper.isValidLongValue(bytes, startOffset, true)) {
+ return false;
+ }
+
+ long position = ATypeHierarchy.getLongValue(functionIdentifier.getName(), 1, bytes, startOffset);
+
+ // Ensure the position is between 1 and 64 (int64 has 64 bits)
+ if (position < 1 || position > 64) {
+ return false;
+ }
+
+ longResult = applyBitwiseOperation(longResult, position);
+
+ return true;
+ }
+}
diff --git a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/bitwise/BitAndDescriptor.java b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/bitwise/BitAndDescriptor.java
new file mode 100644
index 0000000..175c078
--- /dev/null
+++ b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/bitwise/BitAndDescriptor.java
@@ -0,0 +1,59 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.asterix.runtime.evaluators.functions.bitwise;
+
+import org.apache.asterix.common.annotations.MissingNullInOutFunction;
+import org.apache.asterix.om.functions.BuiltinFunctions;
+import org.apache.asterix.om.functions.IFunctionDescriptorFactory;
+import org.apache.asterix.runtime.evaluators.base.AbstractScalarFunctionDynamicDescriptor;
+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;
+
+@MissingNullInOutFunction
+public class BitAndDescriptor extends AbstractScalarFunctionDynamicDescriptor {
+
+ public static final IFunctionDescriptorFactory FACTORY = BitAndDescriptor::new;
+
+ @Override
+ public FunctionIdentifier getIdentifier() {
+ return BuiltinFunctions.BIT_AND;
+ }
+
+ @Override
+ public IScalarEvaluatorFactory createEvaluatorFactory(final IScalarEvaluatorFactory[] args) {
+ return new IScalarEvaluatorFactory() {
+ private static final long serialVersionUID = 1L;
+
+ @Override
+ public IScalarEvaluator createScalarEvaluator(final IHyracksTaskContext ctx) throws HyracksDataException {
+ return new AbstractBitMultipleValuesEvaluator(ctx, args, getIdentifier(), sourceLoc) {
+
+ @Override
+ long applyBitwiseOperation(long value1, long value2) {
+ return value1 & value2;
+ }
+ };
+ }
+ };
+ }
+}
diff --git a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/bitwise/BitClearDescriptor.java b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/bitwise/BitClearDescriptor.java
new file mode 100644
index 0000000..f2a11051
--- /dev/null
+++ b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/bitwise/BitClearDescriptor.java
@@ -0,0 +1,59 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.asterix.runtime.evaluators.functions.bitwise;
+
+import org.apache.asterix.common.annotations.MissingNullInOutFunction;
+import org.apache.asterix.om.functions.BuiltinFunctions;
+import org.apache.asterix.om.functions.IFunctionDescriptorFactory;
+import org.apache.asterix.runtime.evaluators.base.AbstractScalarFunctionDynamicDescriptor;
+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;
+
+@MissingNullInOutFunction
+public class BitClearDescriptor extends AbstractScalarFunctionDynamicDescriptor {
+
+ public static final IFunctionDescriptorFactory FACTORY = BitClearDescriptor::new;
+
+ @Override
+ public FunctionIdentifier getIdentifier() {
+ return BuiltinFunctions.BIT_CLEAR;
+ }
+
+ @Override
+ public IScalarEvaluatorFactory createEvaluatorFactory(final IScalarEvaluatorFactory[] args) {
+ return new IScalarEvaluatorFactory() {
+ private static final long serialVersionUID = 1L;
+
+ @Override
+ public IScalarEvaluator createScalarEvaluator(final IHyracksTaskContext ctx) throws HyracksDataException {
+ return new AbstractBitValuePositionEvaluator(ctx, args, getIdentifier(), sourceLoc) {
+
+ @Override
+ long applyBitwiseOperation(long value, long position) {
+ return value & ~(1L << (position - 1));
+ }
+ };
+ }
+ };
+ }
+}
diff --git a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/bitwise/BitCountDescriptor.java b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/bitwise/BitCountDescriptor.java
new file mode 100644
index 0000000..6aad01a
--- /dev/null
+++ b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/bitwise/BitCountDescriptor.java
@@ -0,0 +1,76 @@
+/*
+ * 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.bitwise;
+
+import org.apache.asterix.common.annotations.MissingNullInOutFunction;
+import org.apache.asterix.formats.nontagged.SerializerDeserializerProvider;
+import org.apache.asterix.om.base.AMutableInt32;
+import org.apache.asterix.om.functions.BuiltinFunctions;
+import org.apache.asterix.om.functions.IFunctionDescriptorFactory;
+import org.apache.asterix.om.types.BuiltinType;
+import org.apache.asterix.runtime.evaluators.base.AbstractScalarFunctionDynamicDescriptor;
+import org.apache.hyracks.algebricks.core.algebra.functions.FunctionIdentifier;
+import org.apache.hyracks.algebricks.runtime.base.IScalarEvaluator;
+import org.apache.hyracks.algebricks.runtime.base.IScalarEvaluatorFactory;
+import org.apache.hyracks.api.context.IHyracksTaskContext;
+import org.apache.hyracks.api.dataflow.value.ISerializerDeserializer;
+import org.apache.hyracks.api.exceptions.HyracksDataException;
+import org.apache.hyracks.data.std.api.IPointable;
+
+@MissingNullInOutFunction
+public class BitCountDescriptor extends AbstractScalarFunctionDynamicDescriptor {
+
+ public static final IFunctionDescriptorFactory FACTORY = BitCountDescriptor::new;
+
+ @Override
+ public FunctionIdentifier getIdentifier() {
+ return BuiltinFunctions.BIT_COUNT;
+ }
+
+ @Override
+ public IScalarEvaluatorFactory createEvaluatorFactory(final IScalarEvaluatorFactory[] args) {
+ return new IScalarEvaluatorFactory() {
+ private static final long serialVersionUID = 1L;
+
+ private final AMutableInt32 resultMutableInt32 = new AMutableInt32(0);
+ private final ISerializerDeserializer aInt32Serde =
+ SerializerDeserializerProvider.INSTANCE.getSerializerDeserializer(BuiltinType.AINT32);
+
+ @Override
+ public IScalarEvaluator createScalarEvaluator(final IHyracksTaskContext ctx) throws HyracksDataException {
+ return new AbstractBitSingleValueEvaluator(ctx, args, getIdentifier(), sourceLoc) {
+
+ @Override
+ void applyBitwiseOperation(long value) {
+ resultMutableInt32.setValue(Long.bitCount(value));
+ }
+
+ @SuppressWarnings("unchecked")
+ @Override
+ void writeResult(IPointable result) throws HyracksDataException {
+ resultStorage.reset();
+ aInt32Serde.serialize(resultMutableInt32, resultStorage.getDataOutput());
+ result.set(resultStorage);
+ }
+ };
+ }
+ };
+ }
+}
diff --git a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/bitwise/BitNotDescriptor.java b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/bitwise/BitNotDescriptor.java
new file mode 100644
index 0000000..900a261
--- /dev/null
+++ b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/bitwise/BitNotDescriptor.java
@@ -0,0 +1,75 @@
+/*
+ * 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.bitwise;
+
+import org.apache.asterix.common.annotations.MissingNullInOutFunction;
+import org.apache.asterix.formats.nontagged.SerializerDeserializerProvider;
+import org.apache.asterix.om.base.AMutableInt64;
+import org.apache.asterix.om.functions.BuiltinFunctions;
+import org.apache.asterix.om.functions.IFunctionDescriptorFactory;
+import org.apache.asterix.om.types.BuiltinType;
+import org.apache.asterix.runtime.evaluators.base.AbstractScalarFunctionDynamicDescriptor;
+import org.apache.hyracks.algebricks.core.algebra.functions.FunctionIdentifier;
+import org.apache.hyracks.algebricks.runtime.base.IScalarEvaluator;
+import org.apache.hyracks.algebricks.runtime.base.IScalarEvaluatorFactory;
+import org.apache.hyracks.api.context.IHyracksTaskContext;
+import org.apache.hyracks.api.dataflow.value.ISerializerDeserializer;
+import org.apache.hyracks.api.exceptions.HyracksDataException;
+import org.apache.hyracks.data.std.api.IPointable;
+
+@MissingNullInOutFunction
+public class BitNotDescriptor extends AbstractScalarFunctionDynamicDescriptor {
+
+ public static final IFunctionDescriptorFactory FACTORY = BitNotDescriptor::new;
+
+ @Override
+ public FunctionIdentifier getIdentifier() {
+ return BuiltinFunctions.BIT_NOT;
+ }
+
+ @Override
+ public IScalarEvaluatorFactory createEvaluatorFactory(final IScalarEvaluatorFactory[] args) {
+ return new IScalarEvaluatorFactory() {
+ private static final long serialVersionUID = 1L;
+
+ @Override
+ public IScalarEvaluator createScalarEvaluator(final IHyracksTaskContext ctx) throws HyracksDataException {
+ return new AbstractBitSingleValueEvaluator(ctx, args, getIdentifier(), sourceLoc) {
+
+ private final AMutableInt64 resultMutableInt64 = new AMutableInt64(0);
+ private final ISerializerDeserializer aInt64Serde =
+ SerializerDeserializerProvider.INSTANCE.getSerializerDeserializer(BuiltinType.AINT64);
+
+ @Override
+ void applyBitwiseOperation(long value) {
+ resultMutableInt64.setValue(~value);
+ }
+
+ @SuppressWarnings("unchecked")
+ void writeResult(IPointable result) throws HyracksDataException {
+ resultStorage.reset();
+ aInt64Serde.serialize(resultMutableInt64, resultStorage.getDataOutput());
+ result.set(resultStorage);
+ }
+ };
+ }
+ };
+ }
+}
diff --git a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/bitwise/BitOrDescriptor.java b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/bitwise/BitOrDescriptor.java
new file mode 100644
index 0000000..71ffbdc
--- /dev/null
+++ b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/bitwise/BitOrDescriptor.java
@@ -0,0 +1,59 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.asterix.runtime.evaluators.functions.bitwise;
+
+import org.apache.asterix.common.annotations.MissingNullInOutFunction;
+import org.apache.asterix.om.functions.BuiltinFunctions;
+import org.apache.asterix.om.functions.IFunctionDescriptorFactory;
+import org.apache.asterix.runtime.evaluators.base.AbstractScalarFunctionDynamicDescriptor;
+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;
+
+@MissingNullInOutFunction
+public class BitOrDescriptor extends AbstractScalarFunctionDynamicDescriptor {
+
+ public static final IFunctionDescriptorFactory FACTORY = BitOrDescriptor::new;
+
+ @Override
+ public FunctionIdentifier getIdentifier() {
+ return BuiltinFunctions.BIT_OR;
+ }
+
+ @Override
+ public IScalarEvaluatorFactory createEvaluatorFactory(final IScalarEvaluatorFactory[] args) {
+ return new IScalarEvaluatorFactory() {
+ private static final long serialVersionUID = 1L;
+
+ @Override
+ public IScalarEvaluator createScalarEvaluator(final IHyracksTaskContext ctx) throws HyracksDataException {
+ return new AbstractBitMultipleValuesEvaluator(ctx, args, getIdentifier(), sourceLoc) {
+
+ @Override
+ long applyBitwiseOperation(long value1, long value2) {
+ return value1 | value2;
+ }
+ };
+ }
+ };
+ }
+}
diff --git a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/bitwise/BitSetDescriptor.java b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/bitwise/BitSetDescriptor.java
new file mode 100644
index 0000000..82a519a
--- /dev/null
+++ b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/bitwise/BitSetDescriptor.java
@@ -0,0 +1,59 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.asterix.runtime.evaluators.functions.bitwise;
+
+import org.apache.asterix.common.annotations.MissingNullInOutFunction;
+import org.apache.asterix.om.functions.BuiltinFunctions;
+import org.apache.asterix.om.functions.IFunctionDescriptorFactory;
+import org.apache.asterix.runtime.evaluators.base.AbstractScalarFunctionDynamicDescriptor;
+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;
+
+@MissingNullInOutFunction
+public class BitSetDescriptor extends AbstractScalarFunctionDynamicDescriptor {
+
+ public static final IFunctionDescriptorFactory FACTORY = BitSetDescriptor::new;
+
+ @Override
+ public FunctionIdentifier getIdentifier() {
+ return BuiltinFunctions.BIT_SET;
+ }
+
+ @Override
+ public IScalarEvaluatorFactory createEvaluatorFactory(final IScalarEvaluatorFactory[] args) {
+ return new IScalarEvaluatorFactory() {
+ private static final long serialVersionUID = 1L;
+
+ @Override
+ public IScalarEvaluator createScalarEvaluator(final IHyracksTaskContext ctx) throws HyracksDataException {
+ return new AbstractBitValuePositionEvaluator(ctx, args, getIdentifier(), sourceLoc) {
+
+ @Override
+ long applyBitwiseOperation(long value, long position) {
+ return value | (1L << (position - 1));
+ }
+ };
+ }
+ };
+ }
+}
diff --git a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/bitwise/BitShiftWithRotateFlagDescriptor.java b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/bitwise/BitShiftWithRotateFlagDescriptor.java
new file mode 100644
index 0000000..734e689
--- /dev/null
+++ b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/bitwise/BitShiftWithRotateFlagDescriptor.java
@@ -0,0 +1,53 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.asterix.runtime.evaluators.functions.bitwise;
+
+import org.apache.asterix.common.annotations.MissingNullInOutFunction;
+import org.apache.asterix.om.functions.BuiltinFunctions;
+import org.apache.asterix.om.functions.IFunctionDescriptorFactory;
+import org.apache.asterix.runtime.evaluators.base.AbstractScalarFunctionDynamicDescriptor;
+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;
+
+@MissingNullInOutFunction
+public class BitShiftWithRotateFlagDescriptor extends AbstractScalarFunctionDynamicDescriptor {
+
+ public static final IFunctionDescriptorFactory FACTORY = BitShiftWithRotateFlagDescriptor::new;
+
+ @Override
+ public FunctionIdentifier getIdentifier() {
+ return BuiltinFunctions.BIT_SHIFT_WITH_ROTATE_FLAG;
+ }
+
+ @Override
+ public IScalarEvaluatorFactory createEvaluatorFactory(final IScalarEvaluatorFactory[] args) {
+ return new IScalarEvaluatorFactory() {
+ private static final long serialVersionUID = 1L;
+
+ @Override
+ public IScalarEvaluator createScalarEvaluator(final IHyracksTaskContext ctx) throws HyracksDataException {
+ return new BitValueCountFlagEvaluator(ctx, args, getIdentifier(), sourceLoc);
+ }
+ };
+ }
+}
diff --git a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/bitwise/BitShiftWithoutRotateFlagDescriptor.java b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/bitwise/BitShiftWithoutRotateFlagDescriptor.java
new file mode 100644
index 0000000..ee8f274
--- /dev/null
+++ b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/bitwise/BitShiftWithoutRotateFlagDescriptor.java
@@ -0,0 +1,53 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.asterix.runtime.evaluators.functions.bitwise;
+
+import org.apache.asterix.common.annotations.MissingNullInOutFunction;
+import org.apache.asterix.om.functions.BuiltinFunctions;
+import org.apache.asterix.om.functions.IFunctionDescriptorFactory;
+import org.apache.asterix.runtime.evaluators.base.AbstractScalarFunctionDynamicDescriptor;
+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;
+
+@MissingNullInOutFunction
+public class BitShiftWithoutRotateFlagDescriptor extends AbstractScalarFunctionDynamicDescriptor {
+
+ public static final IFunctionDescriptorFactory FACTORY = BitShiftWithoutRotateFlagDescriptor::new;
+
+ @Override
+ public FunctionIdentifier getIdentifier() {
+ return BuiltinFunctions.BIT_SHIFT_WITHOUT_ROTATE_FLAG;
+ }
+
+ @Override
+ public IScalarEvaluatorFactory createEvaluatorFactory(final IScalarEvaluatorFactory[] args) {
+ return new IScalarEvaluatorFactory() {
+ private static final long serialVersionUID = 1L;
+
+ @Override
+ public IScalarEvaluator createScalarEvaluator(final IHyracksTaskContext ctx) throws HyracksDataException {
+ return new BitValueCountFlagEvaluator(ctx, args, getIdentifier(), sourceLoc);
+ }
+ };
+ }
+}
diff --git a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/bitwise/BitTestWithAllFlagDescriptor.java b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/bitwise/BitTestWithAllFlagDescriptor.java
new file mode 100644
index 0000000..a4412ca
--- /dev/null
+++ b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/bitwise/BitTestWithAllFlagDescriptor.java
@@ -0,0 +1,53 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.asterix.runtime.evaluators.functions.bitwise;
+
+import org.apache.asterix.common.annotations.MissingNullInOutFunction;
+import org.apache.asterix.om.functions.BuiltinFunctions;
+import org.apache.asterix.om.functions.IFunctionDescriptorFactory;
+import org.apache.asterix.runtime.evaluators.base.AbstractScalarFunctionDynamicDescriptor;
+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;
+
+@MissingNullInOutFunction
+public class BitTestWithAllFlagDescriptor extends AbstractScalarFunctionDynamicDescriptor {
+
+ public static final IFunctionDescriptorFactory FACTORY = BitTestWithAllFlagDescriptor::new;
+
+ @Override
+ public FunctionIdentifier getIdentifier() {
+ return BuiltinFunctions.BIT_TEST_WITH_ALL_FLAG;
+ }
+
+ @Override
+ public IScalarEvaluatorFactory createEvaluatorFactory(final IScalarEvaluatorFactory[] args) {
+ return new IScalarEvaluatorFactory() {
+ private static final long serialVersionUID = 1L;
+
+ @Override
+ public IScalarEvaluator createScalarEvaluator(final IHyracksTaskContext ctx) throws HyracksDataException {
+ return new BitValuePositionFlagEvaluator(ctx, args, getIdentifier(), sourceLoc);
+ }
+ };
+ }
+}
diff --git a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/bitwise/BitTestWithoutAllFlagDescriptor.java b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/bitwise/BitTestWithoutAllFlagDescriptor.java
new file mode 100644
index 0000000..44418b0
--- /dev/null
+++ b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/bitwise/BitTestWithoutAllFlagDescriptor.java
@@ -0,0 +1,53 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.asterix.runtime.evaluators.functions.bitwise;
+
+import org.apache.asterix.common.annotations.MissingNullInOutFunction;
+import org.apache.asterix.om.functions.BuiltinFunctions;
+import org.apache.asterix.om.functions.IFunctionDescriptorFactory;
+import org.apache.asterix.runtime.evaluators.base.AbstractScalarFunctionDynamicDescriptor;
+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;
+
+@MissingNullInOutFunction
+public class BitTestWithoutAllFlagDescriptor extends AbstractScalarFunctionDynamicDescriptor {
+
+ public static final IFunctionDescriptorFactory FACTORY = BitTestWithoutAllFlagDescriptor::new;
+
+ @Override
+ public FunctionIdentifier getIdentifier() {
+ return BuiltinFunctions.BIT_TEST_WITHOUT_ALL_FLAG;
+ }
+
+ @Override
+ public IScalarEvaluatorFactory createEvaluatorFactory(final IScalarEvaluatorFactory[] args) {
+ return new IScalarEvaluatorFactory() {
+ private static final long serialVersionUID = 1L;
+
+ @Override
+ public IScalarEvaluator createScalarEvaluator(final IHyracksTaskContext ctx) throws HyracksDataException {
+ return new BitValuePositionFlagEvaluator(ctx, args, getIdentifier(), sourceLoc);
+ }
+ };
+ }
+}
diff --git a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/bitwise/BitValueCountFlagEvaluator.java b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/bitwise/BitValueCountFlagEvaluator.java
new file mode 100644
index 0000000..a97d825
--- /dev/null
+++ b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/bitwise/BitValueCountFlagEvaluator.java
@@ -0,0 +1,171 @@
+/*
+ * 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.bitwise;
+
+import org.apache.asterix.dataflow.data.nontagged.serde.ABooleanSerializerDeserializer;
+import org.apache.asterix.formats.nontagged.SerializerDeserializerProvider;
+import org.apache.asterix.om.base.AMutableInt64;
+import org.apache.asterix.om.types.ATypeTag;
+import org.apache.asterix.om.types.BuiltinType;
+import org.apache.asterix.om.types.EnumDeserializer;
+import org.apache.asterix.om.types.hierachy.ATypeHierarchy;
+import org.apache.asterix.runtime.evaluators.functions.AbstractScalarEval;
+import org.apache.asterix.runtime.evaluators.functions.PointableHelper;
+import org.apache.hyracks.algebricks.core.algebra.functions.FunctionIdentifier;
+import org.apache.hyracks.algebricks.runtime.base.IScalarEvaluator;
+import org.apache.hyracks.algebricks.runtime.base.IScalarEvaluatorFactory;
+import org.apache.hyracks.api.context.IHyracksTaskContext;
+import org.apache.hyracks.api.dataflow.value.ISerializerDeserializer;
+import org.apache.hyracks.api.exceptions.HyracksDataException;
+import org.apache.hyracks.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;
+
+/**
+ * This function receives three arguments, first argument representing the value, and second argument representing
+ * the number of times to apply the bitwise operation, and third argument (optional) is a boolean flag. This evaluator
+ * is used by the bitwise SHIFT functions.
+ * These functions can be applied only to int64 type numeric values.
+ *
+ * The function has the following behavior:
+ * For the first and second arguments:
+ * - If the argument is missing or null, then missing or null is returned, respectively.
+ * - If the argument is int64, then int64 is returned.
+ * - If the argument is float or double, then int64 or null is returned, depending on the argument value.
+ * - If the argument is any other type, then null is returned.
+ *
+ * For the third argument:
+ * - If the argument is missing or null, then missing or null is returned, respectively.
+ * - If the argument is boolean, then int64 is returned.
+ * - If the argument is any other type, then null is returned.
+ */
+
+class BitValueCountFlagEvaluator extends AbstractScalarEval {
+
+ // Result members
+ private final AMutableInt64 resultMutableInt64 = new AMutableInt64(0);
+ private final ArrayBackedValueStorage resultStorage = new ArrayBackedValueStorage();
+
+ // Evaluators and Pointables
+ private final IScalarEvaluator valueEvaluator;
+ private final IScalarEvaluator countEvaluator;
+ private IScalarEvaluator flagEvaluator;
+ private final IPointable valuePointable = new VoidPointable();
+ private final IPointable countPointable = new VoidPointable();
+ private IPointable flagPointable;
+
+ // Serializer/Deserializer
+ @SuppressWarnings("rawtypes")
+ private final ISerializerDeserializer aInt64Serde =
+ SerializerDeserializerProvider.INSTANCE.getSerializerDeserializer(BuiltinType.AINT64);
+
+ BitValueCountFlagEvaluator(IHyracksTaskContext context, IScalarEvaluatorFactory[] argEvaluatorFactories,
+ FunctionIdentifier functionIdentifier, SourceLocation sourceLocation) throws HyracksDataException {
+ super(sourceLocation, functionIdentifier);
+
+ // Evaluator
+ valueEvaluator = argEvaluatorFactories[0].createScalarEvaluator(context);
+ countEvaluator = argEvaluatorFactories[1].createScalarEvaluator(context);
+ if (argEvaluatorFactories.length > 2) {
+ flagEvaluator = argEvaluatorFactories[2].createScalarEvaluator(context);
+ flagPointable = new VoidPointable();
+ }
+ }
+
+ @SuppressWarnings("unchecked")
+ @Override
+ public void evaluate(IFrameTupleReference tuple, IPointable result) throws HyracksDataException {
+ valueEvaluator.evaluate(tuple, valuePointable);
+ countEvaluator.evaluate(tuple, countPointable);
+
+ if (flagEvaluator != null) {
+ flagEvaluator.evaluate(tuple, flagPointable);
+ }
+
+ if (PointableHelper.checkAndSetMissingOrNull(result, valuePointable, countPointable, flagPointable)) {
+ return;
+ }
+
+ // First argument
+ byte[] valueBytes = valuePointable.getByteArray();
+ int valueStartOffset = valuePointable.getStartOffset();
+
+ // Type and value validity check
+ if (!PointableHelper.isValidLongValue(valueBytes, valueStartOffset, true)) {
+ PointableHelper.setNull(result);
+ return;
+ }
+
+ // Second argument
+ byte[] countBytes = countPointable.getByteArray();
+ int countStartOffset = countPointable.getStartOffset();
+
+ // Type and Value validity check
+ if (!PointableHelper.isValidLongValue(countBytes, countStartOffset, true)) {
+ PointableHelper.setNull(result);
+ return;
+ }
+
+ // Third argument
+ boolean isRotate = false;
+ if (flagEvaluator != null) {
+ byte[] flagBytes = flagPointable.getByteArray();
+ int flagStartOffset = flagPointable.getStartOffset();
+ ATypeTag flagTypeTag = EnumDeserializer.ATYPETAGDESERIALIZER.deserialize(flagBytes[flagStartOffset]);
+
+ if (flagTypeTag != ATypeTag.BOOLEAN) {
+ PointableHelper.setNull(result);
+ return;
+ }
+
+ isRotate = ABooleanSerializerDeserializer.getBoolean(flagBytes, flagStartOffset + 1);
+ }
+
+ // Result holder and count
+ long longValue = ATypeHierarchy.getLongValue(functionIdentifier.getName(), 0, valueBytes, valueStartOffset);
+ long count = ATypeHierarchy.getLongValue(functionIdentifier.getName(), 1, countBytes, countStartOffset);
+
+ // Positive value is left shifting, negative value is right shifting, rotate if needed, do nothing on 0 count
+ // Note, when rotating, for each 64 bits, the rotation is repeated, so rotating by 1 is same as rotating by 65,
+ // rotating by 2 is same as rotating by 66, so we can make the rotation count % 64
+ if (count > 0) {
+ if (isRotate) {
+ longValue = Long.rotateLeft(longValue, (int) (count % 64));
+ } else {
+ longValue = longValue << count;
+ }
+ }
+
+ if (count < 0) {
+ if (isRotate) {
+ longValue = Long.rotateRight(longValue, (int) Math.abs((count % -64)));
+ } else {
+ longValue = longValue >> Math.abs(count);
+ }
+ }
+
+ resultStorage.reset();
+ resultMutableInt64.setValue(longValue);
+ aInt64Serde.serialize(resultMutableInt64, resultStorage.getDataOutput());
+ result.set(resultStorage);
+ }
+}
diff --git a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/bitwise/BitValuePositionFlagEvaluator.java b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/bitwise/BitValuePositionFlagEvaluator.java
new file mode 100644
index 0000000..7d68bc4
--- /dev/null
+++ b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/bitwise/BitValuePositionFlagEvaluator.java
@@ -0,0 +1,275 @@
+/*
+ * 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.bitwise;
+
+import java.io.IOException;
+
+import org.apache.asterix.dataflow.data.nontagged.serde.ABooleanSerializerDeserializer;
+import org.apache.asterix.formats.nontagged.SerializerDeserializerProvider;
+import org.apache.asterix.om.base.ABoolean;
+import org.apache.asterix.om.types.ATypeTag;
+import org.apache.asterix.om.types.BuiltinType;
+import org.apache.asterix.om.types.EnumDeserializer;
+import org.apache.asterix.om.types.hierachy.ATypeHierarchy;
+import org.apache.asterix.runtime.evaluators.common.ListAccessor;
+import org.apache.asterix.runtime.evaluators.functions.AbstractScalarEval;
+import org.apache.asterix.runtime.evaluators.functions.PointableHelper;
+import org.apache.hyracks.algebricks.core.algebra.functions.FunctionIdentifier;
+import org.apache.hyracks.algebricks.runtime.base.IScalarEvaluator;
+import org.apache.hyracks.algebricks.runtime.base.IScalarEvaluatorFactory;
+import org.apache.hyracks.api.context.IHyracksTaskContext;
+import org.apache.hyracks.api.dataflow.value.ISerializerDeserializer;
+import org.apache.hyracks.api.exceptions.HyracksDataException;
+import org.apache.hyracks.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;
+
+/**
+ * This function receives two or three arguments, first argument representing the value, second argument representing
+ * the position to apply the operation at, and third argument (optional) represents a boolean flag. The position can
+ * be a single value or an array of values. This evaluator is used by the bitwise BITTEST and ISBITSET
+ * functions.
+ *
+ * These functions can be applied only to int64 type numeric values.
+ *
+ * The function has the following behavior:
+ * For the first argument:
+ * - If the argument is missing or null, then missing or null is returned, respectively.
+ * - If the argument is int64, then boolean is returned.
+ * - If the argument is float or double, then boolean or null is returned, depending on the argument value.
+ * - If the argument is any other type, then null is returned.
+ *
+ * For the second argument:
+ * - If the argument is missing or null, then missing or null is returned, respectively.
+ * - If the argument is int64, then boolean is returned.
+ * - If the argument is float or double, then boolean or null is returned, depending on the argument value.
+ * - If the argument is an array:
+ * - If the array item type is int64, then int64 or boolean is returned.
+ * - If the array item type is float or double, then boolean or null is returned, depending on the argument.
+ * - If the array item type is any other type, then null is returned.
+ * - If the argument is any other type, then null is returned.
+ *
+ * For the third argument:
+ * - If the argument is missing or null, then missing or null is returned, respectively.
+ * - If the argument is boolean, then boolean is returned.
+ * - If the argument is any other type, then null is returned.
+ */
+
+class BitValuePositionFlagEvaluator extends AbstractScalarEval {
+
+ // Result members
+ private ABoolean resultBoolean;
+ private final ArrayBackedValueStorage resultStorage = new ArrayBackedValueStorage();
+
+ // This flag has a special purpose. In some cases, when an array of positions is passed, checking
+ // some arguments might be enough to return the final result, but, instead of stopping, we need to
+ // continue looping because if any value in array is invalid, we should return a null instead of
+ // the boolean result, this flag will keep the loop going just for checking the values, while the
+ // final result is already set previously.
+ private boolean isStopUpdatingResultBoolean = false;
+
+ // Evaluators and Pointables
+ private final IScalarEvaluator valueEvaluator;
+ private final IScalarEvaluator positionEvaluator;
+ private IScalarEvaluator flagEvaluator;
+ private final IPointable valuePointable = new VoidPointable();
+ private final IPointable positionPointable = new VoidPointable();
+ private IPointable flagPointable;
+
+ // List accessor
+ private final ListAccessor listAccessor = new ListAccessor();
+ private final IPointable listItemPointable = new VoidPointable();
+
+ // Serializer/Deserializer
+ @SuppressWarnings("rawtypes")
+ private final ISerializerDeserializer aBooleanSerde =
+ SerializerDeserializerProvider.INSTANCE.getSerializerDeserializer(BuiltinType.ABOOLEAN);
+
+ BitValuePositionFlagEvaluator(IHyracksTaskContext context, IScalarEvaluatorFactory[] argEvaluatorFactories,
+ FunctionIdentifier functionIdentifier, SourceLocation sourceLocation) throws HyracksDataException {
+ super(sourceLocation, functionIdentifier);
+
+ // Evaluators
+ valueEvaluator = argEvaluatorFactories[0].createScalarEvaluator(context);
+ positionEvaluator = argEvaluatorFactories[1].createScalarEvaluator(context);
+
+ if (argEvaluatorFactories.length > 2) {
+ flagEvaluator = argEvaluatorFactories[2].createScalarEvaluator(context);
+ flagPointable = new VoidPointable();
+ }
+ }
+
+ @SuppressWarnings("unchecked")
+ @Override
+ public void evaluate(IFrameTupleReference tuple, IPointable result) throws HyracksDataException {
+
+ valueEvaluator.evaluate(tuple, valuePointable);
+ positionEvaluator.evaluate(tuple, positionPointable);
+
+ if (flagEvaluator != null) {
+ flagEvaluator.evaluate(tuple, flagPointable);
+ }
+
+ if (PointableHelper.checkAndSetMissingOrNull(result, valuePointable, positionPointable, flagPointable)) {
+ return;
+ }
+
+ // Value argument
+ byte[] valueBytes = valuePointable.getByteArray();
+ int valueStartOffset = valuePointable.getStartOffset();
+
+ // Type and value validity check
+ if (!PointableHelper.isValidLongValue(valueBytes, valueStartOffset, true)) {
+ PointableHelper.setNull(result);
+ return;
+ }
+
+ // Position argument
+ byte[] positionBytes = positionPointable.getByteArray();
+ int positionStartOffset = positionPointable.getStartOffset();
+ ATypeTag positionTypeTag =
+ EnumDeserializer.ATYPETAGDESERIALIZER.deserialize(positionBytes[positionStartOffset]);
+
+ // Type validity check (for position argument, array is a valid type as well)
+ if (!ATypeHierarchy.canPromote(positionTypeTag, ATypeTag.DOUBLE) && positionTypeTag != ATypeTag.ARRAY) {
+ PointableHelper.setNull(result);
+ return;
+ }
+
+ // Third argument
+ boolean isAllSet = false;
+ if (flagEvaluator != null) {
+ byte[] flagBytes = flagPointable.getByteArray();
+ int flagStartOffset = flagPointable.getStartOffset();
+ ATypeTag flagTypeTag = EnumDeserializer.ATYPETAGDESERIALIZER.deserialize(flagBytes[flagStartOffset]);
+
+ if (flagTypeTag != ATypeTag.BOOLEAN) {
+ PointableHelper.setNull(result);
+ return;
+ }
+
+ isAllSet = ABooleanSerializerDeserializer.getBoolean(flagBytes, flagStartOffset + 1);
+ }
+
+ // Result long value
+ long longResult = ATypeHierarchy.getLongValue(functionIdentifier.getName(), 0, valueBytes, valueStartOffset);
+
+ // If any operation returns false, the result should be null
+ boolean isSuccessfulOperation;
+
+ // From here onward, we got valid arguments, so let's handle numeric or array position argument
+ if (positionTypeTag != ATypeTag.ARRAY) {
+ isSuccessfulOperation =
+ applyBitWiseOperationWithNumericAsPosition(longResult, positionBytes, positionStartOffset);
+ } else {
+ isSuccessfulOperation =
+ applyBitWiseOperationWithArrayAsPosition(longResult, positionBytes, positionStartOffset, isAllSet);
+ }
+
+ if (!isSuccessfulOperation) {
+ PointableHelper.setNull(result);
+ return;
+ }
+
+ // Write the result
+ resultStorage.reset();
+ aBooleanSerde.serialize(resultBoolean, resultStorage.getDataOutput());
+ result.set(resultStorage);
+ }
+
+ /**
+ * This method applies the bitwise operation on the int64 value at the specified positions in
+ * the array.
+ *
+ * @param value The long value
+ * @param bytes bytes of the position
+ * @param startOffset start offset of the position
+ * @param isAllSet is AllSet check flag
+ * @return returns {@code true} if all operations are successful, {@code false} otherwise.
+ *
+ * @throws HyracksDataException HyracksDataException
+ */
+ private boolean applyBitWiseOperationWithArrayAsPosition(long value, byte[] bytes, int startOffset,
+ boolean isAllSet) throws HyracksDataException {
+
+ listAccessor.reset(bytes, startOffset);
+
+ // In case of an empty array, we return the value as is without change
+ if (listAccessor.size() == 0) {
+ return true;
+ }
+
+ try {
+ // For each item in the array, apply the bitwise operation at that position
+ for (int i = 0; i < listAccessor.size(); i++) {
+ listAccessor.getOrWriteItem(i, listItemPointable, resultStorage);
+
+ byte[] itemBytes = listItemPointable.getByteArray();
+ int itemStartOffset = listItemPointable.getStartOffset();
+
+ if (!applyBitWiseOperationWithNumericAsPosition(value, itemBytes, itemStartOffset)) {
+ return false;
+ }
+
+ // Based on the isAllSet flag, we might want to stop re-calculating the result, this
+ // isStopUpdatingResultBoolean keeps an eye on that.
+ isStopUpdatingResultBoolean =
+ !isAllSet ? resultBoolean == ABoolean.TRUE : resultBoolean == ABoolean.FALSE;
+ }
+
+ return true;
+ } catch (IOException ex) {
+ throw HyracksDataException.create(ex);
+ }
+ }
+
+ /**
+ * This method applies the bitwise operation on the int64 value at the specified position.
+ *
+ * @param value the long value
+ * @param bytes data bytes
+ * @param startOffset start offset
+ * @return returns {@code true} if all operations are successful, {@code false} otherwise.
+ */
+ private boolean applyBitWiseOperationWithNumericAsPosition(long value, byte[] bytes, int startOffset)
+ throws HyracksDataException {
+
+ // Value validity check
+ if (!PointableHelper.isValidLongValue(bytes, startOffset, true)) {
+ return false;
+ }
+
+ long position = ATypeHierarchy.getLongValue(functionIdentifier.getName(), 1, bytes, startOffset);
+
+ // Ensure the position is between 1 and 64 (int64 has 64 bits)
+ if (position < 1 || position > 64) {
+ return false;
+ }
+
+ // Checks if a certain position is bit 1
+ if (!isStopUpdatingResultBoolean) {
+ resultBoolean = (value & (1L << (position - 1))) != 0 ? ABoolean.TRUE : ABoolean.FALSE;
+ }
+
+ return true;
+ }
+}
diff --git a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/bitwise/BitXorDescriptor.java b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/bitwise/BitXorDescriptor.java
new file mode 100644
index 0000000..afd3cbf
--- /dev/null
+++ b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/bitwise/BitXorDescriptor.java
@@ -0,0 +1,59 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.asterix.runtime.evaluators.functions.bitwise;
+
+import org.apache.asterix.common.annotations.MissingNullInOutFunction;
+import org.apache.asterix.om.functions.BuiltinFunctions;
+import org.apache.asterix.om.functions.IFunctionDescriptorFactory;
+import org.apache.asterix.runtime.evaluators.base.AbstractScalarFunctionDynamicDescriptor;
+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;
+
+@MissingNullInOutFunction
+public class BitXorDescriptor extends AbstractScalarFunctionDynamicDescriptor {
+
+ public static final IFunctionDescriptorFactory FACTORY = BitXorDescriptor::new;
+
+ @Override
+ public FunctionIdentifier getIdentifier() {
+ return BuiltinFunctions.BIT_XOR;
+ }
+
+ @Override
+ public IScalarEvaluatorFactory createEvaluatorFactory(final IScalarEvaluatorFactory[] args) {
+ return new IScalarEvaluatorFactory() {
+ private static final long serialVersionUID = 1L;
+
+ @Override
+ public IScalarEvaluator createScalarEvaluator(final IHyracksTaskContext ctx) throws HyracksDataException {
+ return new AbstractBitMultipleValuesEvaluator(ctx, args, getIdentifier(), sourceLoc) {
+
+ @Override
+ long applyBitwiseOperation(long value1, long value2) {
+ return value1 ^ value2;
+ }
+ };
+ }
+ };
+ }
+}
diff --git a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/bitwise/IsBitSetWithAllFlagDescriptor.java b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/bitwise/IsBitSetWithAllFlagDescriptor.java
new file mode 100644
index 0000000..6bc9abf
--- /dev/null
+++ b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/bitwise/IsBitSetWithAllFlagDescriptor.java
@@ -0,0 +1,53 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.asterix.runtime.evaluators.functions.bitwise;
+
+import org.apache.asterix.common.annotations.MissingNullInOutFunction;
+import org.apache.asterix.om.functions.BuiltinFunctions;
+import org.apache.asterix.om.functions.IFunctionDescriptorFactory;
+import org.apache.asterix.runtime.evaluators.base.AbstractScalarFunctionDynamicDescriptor;
+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;
+
+@MissingNullInOutFunction
+public class IsBitSetWithAllFlagDescriptor extends AbstractScalarFunctionDynamicDescriptor {
+
+ public static final IFunctionDescriptorFactory FACTORY = IsBitSetWithAllFlagDescriptor::new;
+
+ @Override
+ public FunctionIdentifier getIdentifier() {
+ return BuiltinFunctions.IS_BIT_SET_WITH_ALL_FLAG;
+ }
+
+ @Override
+ public IScalarEvaluatorFactory createEvaluatorFactory(final IScalarEvaluatorFactory[] args) {
+ return new IScalarEvaluatorFactory() {
+ private static final long serialVersionUID = 1L;
+
+ @Override
+ public IScalarEvaluator createScalarEvaluator(final IHyracksTaskContext ctx) throws HyracksDataException {
+ return new BitValuePositionFlagEvaluator(ctx, args, getIdentifier(), sourceLoc);
+ }
+ };
+ }
+}
diff --git a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/bitwise/IsBitSetWithoutAllFlagDescriptor.java b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/bitwise/IsBitSetWithoutAllFlagDescriptor.java
new file mode 100644
index 0000000..bb4763a
--- /dev/null
+++ b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/bitwise/IsBitSetWithoutAllFlagDescriptor.java
@@ -0,0 +1,53 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.asterix.runtime.evaluators.functions.bitwise;
+
+import org.apache.asterix.common.annotations.MissingNullInOutFunction;
+import org.apache.asterix.om.functions.BuiltinFunctions;
+import org.apache.asterix.om.functions.IFunctionDescriptorFactory;
+import org.apache.asterix.runtime.evaluators.base.AbstractScalarFunctionDynamicDescriptor;
+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;
+
+@MissingNullInOutFunction
+public class IsBitSetWithoutAllFlagDescriptor extends AbstractScalarFunctionDynamicDescriptor {
+
+ public static final IFunctionDescriptorFactory FACTORY = IsBitSetWithoutAllFlagDescriptor::new;
+
+ @Override
+ public FunctionIdentifier getIdentifier() {
+ return BuiltinFunctions.IS_BIT_SET_WITHOUT_ALL_FLAG;
+ }
+
+ @Override
+ public IScalarEvaluatorFactory createEvaluatorFactory(final IScalarEvaluatorFactory[] args) {
+ return new IScalarEvaluatorFactory() {
+ private static final long serialVersionUID = 1L;
+
+ @Override
+ public IScalarEvaluator createScalarEvaluator(final IHyracksTaskContext ctx) throws HyracksDataException {
+ return new BitValuePositionFlagEvaluator(ctx, args, getIdentifier(), sourceLoc);
+ }
+ };
+ }
+}
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 13af5a1..088b25c 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
@@ -440,6 +440,19 @@
import org.apache.asterix.runtime.evaluators.functions.binary.PrintBinaryDescriptor;
import org.apache.asterix.runtime.evaluators.functions.binary.SubBinaryFromDescriptor;
import org.apache.asterix.runtime.evaluators.functions.binary.SubBinaryFromToDescriptor;
+import org.apache.asterix.runtime.evaluators.functions.bitwise.BitAndDescriptor;
+import org.apache.asterix.runtime.evaluators.functions.bitwise.BitClearDescriptor;
+import org.apache.asterix.runtime.evaluators.functions.bitwise.BitCountDescriptor;
+import org.apache.asterix.runtime.evaluators.functions.bitwise.BitNotDescriptor;
+import org.apache.asterix.runtime.evaluators.functions.bitwise.BitOrDescriptor;
+import org.apache.asterix.runtime.evaluators.functions.bitwise.BitSetDescriptor;
+import org.apache.asterix.runtime.evaluators.functions.bitwise.BitShiftWithRotateFlagDescriptor;
+import org.apache.asterix.runtime.evaluators.functions.bitwise.BitShiftWithoutRotateFlagDescriptor;
+import org.apache.asterix.runtime.evaluators.functions.bitwise.BitTestWithAllFlagDescriptor;
+import org.apache.asterix.runtime.evaluators.functions.bitwise.BitTestWithoutAllFlagDescriptor;
+import org.apache.asterix.runtime.evaluators.functions.bitwise.BitXorDescriptor;
+import org.apache.asterix.runtime.evaluators.functions.bitwise.IsBitSetWithAllFlagDescriptor;
+import org.apache.asterix.runtime.evaluators.functions.bitwise.IsBitSetWithoutAllFlagDescriptor;
import org.apache.asterix.runtime.evaluators.functions.records.FieldAccessByIndexDescriptor;
import org.apache.asterix.runtime.evaluators.functions.records.FieldAccessByNameDescriptor;
import org.apache.asterix.runtime.evaluators.functions.records.FieldAccessNestedDescriptor;
@@ -910,6 +923,21 @@
fc.add(FindBinaryDescriptor.FACTORY);
fc.add(FindBinaryFromDescriptor.FACTORY);
+ // Bitwise functions
+ fc.add(BitAndDescriptor.FACTORY);
+ fc.add(BitOrDescriptor.FACTORY);
+ fc.add(BitXorDescriptor.FACTORY);
+ fc.add(BitNotDescriptor.FACTORY);
+ fc.add(BitCountDescriptor.FACTORY);
+ fc.add(BitSetDescriptor.FACTORY);
+ fc.add(BitClearDescriptor.FACTORY);
+ fc.add(BitShiftWithoutRotateFlagDescriptor.FACTORY);
+ fc.add(BitShiftWithRotateFlagDescriptor.FACTORY);
+ fc.add(BitTestWithoutAllFlagDescriptor.FACTORY);
+ fc.add(BitTestWithAllFlagDescriptor.FACTORY);
+ fc.add(IsBitSetWithoutAllFlagDescriptor.FACTORY);
+ fc.add(IsBitSetWithAllFlagDescriptor.FACTORY);
+
// String functions
fc.add(StringLikeDescriptor.FACTORY);
fc.add(StringContainsDescriptor.FACTORY);