[ASTERIXDB-2634][FUN] String functions to return null on data/type errors
- user model changes: no
- storage format changes: no
- interface changes: no
Details:
- substring(string, int, int)
- codepoint-to-string([int])
- string-concat([string])
Change-Id: I17905ad9e767b43822d28a46123bc1390a159cc7
Reviewed-on: https://asterix-gerrit.ics.uci.edu/c/asterixdb/+/4083
Contrib: Jenkins <jenkins@fulliautomatix.ics.uci.edu>
Integration-Tests: Jenkins <jenkins@fulliautomatix.ics.uci.edu>
Tested-by: Jenkins <jenkins@fulliautomatix.ics.uci.edu>
Reviewed-by: Hussain Towaileb <hussainht@gmail.com>
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/fun_return_null/string_fun/string_fun_004/string_fun_004.01.ddl.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/fun_return_null/string_fun/string_fun_004/string_fun_004.01.ddl.sqlpp
new file mode 100644
index 0000000..ac0c8ae
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/fun_return_null/string_fun/string_fun_004/string_fun_004.01.ddl.sqlpp
@@ -0,0 +1,40 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+drop dataverse test if exists;
+create dataverse test;
+use test;
+
+create type dsType as {
+id: int,
+i8: int8,
+i16: int16,
+i32: int32,
+i64: int64,
+f: float,
+d: double,
+str1: string
+};
+
+create type openType as {
+id: int
+};
+
+create dataset DS(dsType) primary key id;
+create dataset openDS(openType) primary key id;
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/fun_return_null/string_fun/string_fun_004/string_fun_004.02.update.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/fun_return_null/string_fun/string_fun_004/string_fun_004.02.update.sqlpp
new file mode 100644
index 0000000..eea9d0c
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/fun_return_null/string_fun/string_fun_004/string_fun_004.02.update.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.
+ */
+
+use test;
+
+insert into DS([
+{"id": 1, "i8": int8("-2"), "i16": int16("10"), "i32": int32("21"), "i64": int64("87"), "f": float("4.2"), "d": double("5.0"), "str1": "foo", "mixed": 7},
+{"id": 2, "i8": int8("0"), "i16": int16("-10"), "i32": int32("21"), "i64": int64("87"), "f": float("4.2"), "d": double("5.3"), "str1": "foo", "mixed": "m"}
+]);
+
+insert into openDS([
+{"id": 1, "i8": int8("-2"), "i16": int16("10"), "i32": int32("21"), "i64": int64("87"), "f": float("4.2"), "d": double("5.0"), "str1": "foo", "mixed": 7},
+{"id": 2, "i8": int8("0"), "i16": int16("-10"), "i32": int32("21"), "i64": int64("87"), "f": float("4.2"), "d": double("5.3"), "str1": "foo", "mixed": "m"}
+]);
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/fun_return_null/string_fun/string_fun_004/string_fun_004.03.query.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/fun_return_null/string_fun/string_fun_004/string_fun_004.03.query.sqlpp
new file mode 100644
index 0000000..5ecc261
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/fun_return_null/string_fun/string_fun_004/string_fun_004.03.query.sqlpp
@@ -0,0 +1,36 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+/*
+ * Description: tests that string functions do not throw exception on type/data errors
+ */
+// requesttype=application/json
+// param max-warnings:json=1000
+
+use test;
+
+from DS as ds
+select
+`string-concat`([ds.str1, ds.i8]),
+"str" || ds.mixed,
+substring("hello world", ds.str1, ds.i8),
+substring(ds.mixed, 0, 1),
+`codepoint-to-string`(ds.str1),
+`codepoint-to-string`([ds.mixed])
+order by ds.id;
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/fun_return_null/string_fun/string_fun_004/string_fun_004.04.query.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/fun_return_null/string_fun/string_fun_004/string_fun_004.04.query.sqlpp
new file mode 100644
index 0000000..3042334
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/fun_return_null/string_fun/string_fun_004/string_fun_004.04.query.sqlpp
@@ -0,0 +1,36 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+/*
+ * Description: tests that string functions do not throw exception on type/data errors
+ */
+// requesttype=application/json
+// param max-warnings:json=1000
+
+use test;
+
+from openDS as ds
+select
+`string-concat`([ds.str1, ds.i8]),
+"str" || ds.mixed,
+substring("hello world", ds.str1, ds.i8),
+substring(ds.mixed, 0, 1),
+`codepoint-to-string`(ds.str1),
+`codepoint-to-string`([ds.mixed])
+order by ds.id;
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/fun_return_null/string_fun/string_fun_004/string_fun_004.05.query.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/fun_return_null/string_fun/string_fun_004/string_fun_004.05.query.sqlpp
new file mode 100644
index 0000000..6036007
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/fun_return_null/string_fun/string_fun_004/string_fun_004.05.query.sqlpp
@@ -0,0 +1,35 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+/*
+ * Description: tests that string functions do not throw exception on type/data errors
+ */
+// requesttype=application/json
+// param max-warnings:json=1000
+
+use test;
+
+
+select
+`string-concat`(["str", 9]),
+"str" || int8("9"),
+substring("hello world", "str", 3),
+`codepoint-to-string`("str"),
+`codepoint-to-string`(["str"]),
+`codepoint-to-string`([5.5]);
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/fun_return_null/string_fun/string_fun_004/string_fun_004.06.ddl.sqlpp b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/fun_return_null/string_fun/string_fun_004/string_fun_004.06.ddl.sqlpp
new file mode 100644
index 0000000..548e632
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/queries_sqlpp/fun_return_null/string_fun/string_fun_004/string_fun_004.06.ddl.sqlpp
@@ -0,0 +1,20 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+drop dataverse test if exists;
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/results/fun_return_null/string_fun/string_fun_004/string_fun_004.03.adm b/asterixdb/asterix-app/src/test/resources/runtimets/results/fun_return_null/string_fun/string_fun_004/string_fun_004.03.adm
new file mode 100644
index 0000000..2bc8a4b
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/results/fun_return_null/string_fun/string_fun_004/string_fun_004.03.adm
@@ -0,0 +1,2 @@
+{ "$1": null, "$2": null, "$3": null, "$4": null, "$5": null, "$6": "\u0007" }
+{ "$1": null, "$2": "strm", "$3": null, "$4": "m", "$5": null, "$6": null }
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/results/fun_return_null/string_fun/string_fun_004/string_fun_004.04.adm b/asterixdb/asterix-app/src/test/resources/runtimets/results/fun_return_null/string_fun/string_fun_004/string_fun_004.04.adm
new file mode 100644
index 0000000..2bc8a4b
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/results/fun_return_null/string_fun/string_fun_004/string_fun_004.04.adm
@@ -0,0 +1,2 @@
+{ "$1": null, "$2": null, "$3": null, "$4": null, "$5": null, "$6": "\u0007" }
+{ "$1": null, "$2": "strm", "$3": null, "$4": "m", "$5": null, "$6": null }
\ No newline at end of file
diff --git a/asterixdb/asterix-app/src/test/resources/runtimets/results/fun_return_null/string_fun/string_fun_004/string_fun_004.05.adm b/asterixdb/asterix-app/src/test/resources/runtimets/results/fun_return_null/string_fun/string_fun_004/string_fun_004.05.adm
new file mode 100644
index 0000000..c89e546
--- /dev/null
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/results/fun_return_null/string_fun/string_fun_004/string_fun_004.05.adm
@@ -0,0 +1 @@
+{ "$1": null, "$2": null, "$3": null, "$4": null, "$5": null, "$6": null }
\ 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 3a0d50b..5bb68e0 100644
--- a/asterixdb/asterix-app/src/test/resources/runtimets/testsuite_sqlpp.xml
+++ b/asterixdb/asterix-app/src/test/resources/runtimets/testsuite_sqlpp.xml
@@ -13606,5 +13606,30 @@
<expected-warn>Invalid value: function substring expects its 2nd input parameter to be an integer value, got Infinity (in line 34, at column 1)</expected-warn>
</compilation-unit>
</test-case>
+ <test-case FilePath="fun_return_null/string_fun" check-warnings="true">
+ <compilation-unit name="string_fun_004">
+ <output-dir compare="Text">string_fun_004</output-dir>
+ <expected-warn>Unsupported type: string-concat cannot process input type tinyint (in line 30, at column 1)</expected-warn>
+ <expected-warn>Type mismatch: function substring expects its 2nd input parameter to be of type tinyint, smallint, integer, bigint, float or double, but the actual input type is string (in line 32, at column 1)</expected-warn>
+ <expected-warn>Type mismatch: function substring expects its 1st input parameter to be of type string, but the actual input type is bigint (in line 33, at column 1)</expected-warn>
+ <expected-warn>Unsupported type: string-concat cannot process input type bigint (in line 31, at column 7)</expected-warn>
+ <expected-warn>Type mismatch: function codepoint-to-string expects its 1st input parameter to be of type array, but the actual input type is string (in line 34, at column 1)</expected-warn>
+ <expected-warn>Unsupported type: codepoint-to-string cannot process input type string (in line 35, at column 1)</expected-warn>
+
+ <expected-warn>Unsupported type: string-concat cannot process input type tinyint (in line 30, at column 1)</expected-warn>
+ <expected-warn>Type mismatch: function substring expects its 2nd input parameter to be of type tinyint, smallint, integer, bigint, float or double, but the actual input type is string (in line 32, at column 1)</expected-warn>
+ <expected-warn>Type mismatch: function substring expects its 1st input parameter to be of type string, but the actual input type is bigint (in line 33, at column 1)</expected-warn>
+ <expected-warn>Unsupported type: string-concat cannot process input type bigint (in line 31, at column 7)</expected-warn>
+ <expected-warn>Type mismatch: function codepoint-to-string expects its 1st input parameter to be of type array, but the actual input type is string (in line 34, at column 1)</expected-warn>
+ <expected-warn>Unsupported type: codepoint-to-string cannot process input type string (in line 35, at column 1)</expected-warn>
+
+ <expected-warn>Unsupported type: string-concat cannot process input type bigint (in line 30, at column 1)</expected-warn>
+ <expected-warn>Unsupported type: string-concat cannot process input type tinyint (in line 31, at column 7)</expected-warn>
+ <expected-warn>Type mismatch: function substring expects its 1st input parameter to be of type string, but the actual input type is bigint (in line 32, at column 1)</expected-warn>
+ <expected-warn>Type mismatch: function codepoint-to-string expects its 1st input parameter to be of type array, but the actual input type is string (in line 33, at column 1)</expected-warn>
+ <expected-warn>Unsupported type: codepoint-to-string cannot process input type string (in line 34, at column 1)</expected-warn>
+ <expected-warn>Unsupported type: codepoint-to-string cannot process input type double (in line 35, at column 1)</expected-warn>
+ </compilation-unit>
+ </test-case>
</test-group>
</test-suite>
diff --git a/asterixdb/asterix-om/src/main/java/org/apache/asterix/dataflow/data/nontagged/serde/AOrderedListSerializerDeserializer.java b/asterixdb/asterix-om/src/main/java/org/apache/asterix/dataflow/data/nontagged/serde/AOrderedListSerializerDeserializer.java
index bffc3b2..e443e13 100644
--- a/asterixdb/asterix-om/src/main/java/org/apache/asterix/dataflow/data/nontagged/serde/AOrderedListSerializerDeserializer.java
+++ b/asterixdb/asterix-om/src/main/java/org/apache/asterix/dataflow/data/nontagged/serde/AOrderedListSerializerDeserializer.java
@@ -116,15 +116,18 @@
listBuilder.write(out, false);
}
+ /** {@code serOrderedList} is untagged. {@code offset} points to the list value (first byte is the item tag) */
public static int getOrderedListLength(byte[] serOrderedList, int offset) {
return AInt32SerializerDeserializer.getInt(serOrderedList, offset + 1);
}
+ /** {@code serOrderedList} is tagged. {@code offset} points to the list tag */
public static int getNumberOfItems(byte[] serOrderedList, int offset) {
// 6 = tag (1) + itemTag (1) + list size (4)
return AInt32SerializerDeserializer.getInt(serOrderedList, offset + 6);
}
+ /** {@code serOrderedList} is tagged. {@code offset} points to the list tag */
public static int getItemOffset(byte[] serOrderedList, int offset, int itemIndex) throws HyracksDataException {
return SerializerDeserializerUtil.getItemOffset(serOrderedList, offset, itemIndex);
}
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 b6c1bf4..53ed003 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
@@ -94,6 +94,7 @@
import org.apache.asterix.om.typecomputer.impl.IfNanOrInfTypeComputer;
import org.apache.asterix.om.typecomputer.impl.IfNullTypeComputer;
import org.apache.asterix.om.typecomputer.impl.InjectFailureTypeComputer;
+import org.apache.asterix.om.typecomputer.impl.Int64ArrayToStringTypeComputer;
import org.apache.asterix.om.typecomputer.impl.LocalAvgTypeComputer;
import org.apache.asterix.om.typecomputer.impl.LocalSingleVarStatisticsTypeComputer;
import org.apache.asterix.om.typecomputer.impl.MinMaxAggTypeComputer;
@@ -127,7 +128,6 @@
import org.apache.asterix.om.typecomputer.impl.SleepTypeComputer;
import org.apache.asterix.om.typecomputer.impl.StringJoinTypeComputer;
import org.apache.asterix.om.typecomputer.impl.SubsetCollectionTypeComputer;
-import org.apache.asterix.om.typecomputer.impl.SubstringTypeComputer;
import org.apache.asterix.om.typecomputer.impl.SwitchCaseComputer;
import org.apache.asterix.om.typecomputer.impl.ToArrayTypeComputer;
import org.apache.asterix.om.typecomputer.impl.ToBigIntTypeComputer;
@@ -1709,14 +1709,14 @@
addFunction(IS_BIT_SET_WITH_ALL_FLAG, BitValuePositionFlagTypeComputer.INSTANCE_TEST_WITH_FLAG, true);
// string functions
- addFunction(STRING_CONSTRUCTOR, AStringTypeComputer.INSTANCE, true); // TODO
+ addFunction(STRING_CONSTRUCTOR, AStringTypeComputer.INSTANCE, true); // TODO(ali)
addFunction(STRING_LIKE, BooleanFunctionTypeComputer.INSTANCE, true);
addFunction(STRING_CONTAINS, UniformInputTypeComputer.STRING_BOOLEAN_INSTANCE, true);
addFunction(STRING_TO_CODEPOINT, UniformInputTypeComputer.STRING_INT64_LIST_INSTANCE, true);
- addFunction(CODEPOINT_TO_STRING, AStringTypeComputer.INSTANCE, true); // TODO
- addFunction(STRING_CONCAT, ConcatTypeComputer.INSTANCE_STRING, true); // TODO
- addFunction(SUBSTRING, SubstringTypeComputer.INSTANCE, true); // TODO
- addFunction(SUBSTRING_OFFSET_1, SubstringTypeComputer.INSTANCE, true); // TODO
+ addFunction(CODEPOINT_TO_STRING, Int64ArrayToStringTypeComputer.INSTANCE, true);
+ addFunction(STRING_CONCAT, ConcatTypeComputer.INSTANCE_STRING, true);
+ addFunction(SUBSTRING, AStringTypeComputer.INSTANCE_NULLABLE, true);
+ addFunction(SUBSTRING_OFFSET_1, AStringTypeComputer.INSTANCE_NULLABLE, true);
addFunction(SUBSTRING2, AStringTypeComputer.INSTANCE_NULLABLE, true);
addFunction(SUBSTRING2_OFFSET_1, AStringTypeComputer.INSTANCE_NULLABLE, true);
addFunction(STRING_LENGTH, UniformInputTypeComputer.STRING_INT64_INSTANCE, true);
diff --git a/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/typecomputer/impl/AStringTypeComputer.java b/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/typecomputer/impl/AStringTypeComputer.java
index 4de96b8..d392e8d 100644
--- a/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/typecomputer/impl/AStringTypeComputer.java
+++ b/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/typecomputer/impl/AStringTypeComputer.java
@@ -27,17 +27,18 @@
public class AStringTypeComputer extends AbstractResultTypeComputer {
- public static final AStringTypeComputer INSTANCE = new AStringTypeComputer(false);
- public static final AStringTypeComputer INSTANCE_NULLABLE = new AStringTypeComputer(true);
+ public static final AStringTypeComputer INSTANCE = new AStringTypeComputer(BuiltinType.ASTRING);
+ public static final AStringTypeComputer INSTANCE_NULLABLE =
+ new AStringTypeComputer(AUnionType.createNullableType(BuiltinType.ASTRING));
- private final boolean nullable;
+ private final IAType outputType;
- private AStringTypeComputer(boolean nullable) {
- this.nullable = nullable;
+ private AStringTypeComputer(IAType outputType) {
+ this.outputType = outputType;
}
@Override
protected IAType getResultType(ILogicalExpression expr, IAType... strippedInputTypes) throws AlgebricksException {
- return nullable ? AUnionType.createNullableType(BuiltinType.ASTRING) : BuiltinType.ASTRING;
+ return outputType;
}
}
diff --git a/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/typecomputer/impl/ConcatTypeComputer.java b/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/typecomputer/impl/ConcatTypeComputer.java
index db59877..c13418f 100644
--- a/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/typecomputer/impl/ConcatTypeComputer.java
+++ b/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/typecomputer/impl/ConcatTypeComputer.java
@@ -43,22 +43,10 @@
protected IAType getResultType(ILogicalExpression expr, IAType... strippedInputTypes) throws AlgebricksException {
IAType argType = strippedInputTypes[0];
IAType outputType = resultType;
- if (!argType.getTypeTag().isListType() || isUnknownable(((AbstractCollectionType) argType).getItemType())) {
+ if (!argType.getTypeTag().isListType()
+ || ((AbstractCollectionType) argType).getItemType().getTypeTag() != outputType.getTypeTag()) {
outputType = AUnionType.createUnknownableType(outputType);
}
return outputType;
}
-
- private boolean isUnknownable(IAType type) {
- switch (type.getTypeTag()) {
- case ANY:
- case MISSING:
- case NULL:
- return true;
- case UNION:
- return ((AUnionType) type).isUnknownableType();
- default:
- return false;
- }
- }
}
diff --git a/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/typecomputer/impl/Int64ArrayToStringTypeComputer.java b/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/typecomputer/impl/Int64ArrayToStringTypeComputer.java
new file mode 100644
index 0000000..318297a
--- /dev/null
+++ b/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/typecomputer/impl/Int64ArrayToStringTypeComputer.java
@@ -0,0 +1,54 @@
+/*
+ * 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 static org.apache.asterix.om.types.ATypeTag.ARRAY;
+import static org.apache.asterix.om.types.ATypeTag.BIGINT;
+
+import org.apache.asterix.om.typecomputer.base.AbstractResultTypeComputer;
+import org.apache.asterix.om.types.AUnionType;
+import org.apache.asterix.om.types.AbstractCollectionType;
+import org.apache.asterix.om.types.BuiltinType;
+import org.apache.asterix.om.types.IAType;
+import org.apache.asterix.om.types.hierachy.ATypeHierarchy;
+import org.apache.hyracks.algebricks.common.exceptions.AlgebricksException;
+import org.apache.hyracks.algebricks.core.algebra.base.ILogicalExpression;
+
+/**
+ * For function signature: string fun([int64])
+ */
+public class Int64ArrayToStringTypeComputer extends AbstractResultTypeComputer {
+
+ public static final Int64ArrayToStringTypeComputer INSTANCE = new Int64ArrayToStringTypeComputer();
+
+ private Int64ArrayToStringTypeComputer() {
+ }
+
+ @Override
+ protected IAType getResultType(ILogicalExpression expr, IAType... strippedInputTypes) throws AlgebricksException {
+ IAType argType = strippedInputTypes[0];
+ return isValid(argType) ? BuiltinType.ASTRING : AUnionType.createUnknownableType(BuiltinType.ASTRING);
+ }
+
+ private static boolean isValid(IAType argType) {
+ return argType.getTypeTag() == ARRAY
+ && ATypeHierarchy.canPromote(((AbstractCollectionType) argType).getItemType().getTypeTag(), BIGINT);
+ }
+}
\ No newline at end of file
diff --git a/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/typecomputer/impl/SubstringTypeComputer.java b/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/typecomputer/impl/SubstringTypeComputer.java
deleted file mode 100644
index ab0b159..0000000
--- a/asterixdb/asterix-om/src/main/java/org/apache/asterix/om/typecomputer/impl/SubstringTypeComputer.java
+++ /dev/null
@@ -1,60 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.asterix.om.typecomputer.impl;
-
-import org.apache.asterix.om.exceptions.TypeMismatchException;
-import org.apache.asterix.om.typecomputer.base.AbstractResultTypeComputer;
-import org.apache.asterix.om.types.ATypeTag;
-import org.apache.asterix.om.types.AUnionType;
-import org.apache.asterix.om.types.BuiltinType;
-import org.apache.asterix.om.types.IAType;
-import org.apache.hyracks.algebricks.common.exceptions.AlgebricksException;
-import org.apache.hyracks.algebricks.core.algebra.base.ILogicalExpression;
-import org.apache.hyracks.algebricks.core.algebra.functions.FunctionIdentifier;
-import org.apache.hyracks.api.exceptions.SourceLocation;
-
-public class SubstringTypeComputer extends AbstractResultTypeComputer {
- public static final SubstringTypeComputer INSTANCE = new SubstringTypeComputer();
-
- @Override
- public void checkArgType(FunctionIdentifier funcId, int argIndex, IAType type, SourceLocation sourceLoc)
- throws AlgebricksException {
- ATypeTag tag = type.getTypeTag();
- if (argIndex == 0 && tag != ATypeTag.STRING) {
- throw new TypeMismatchException(sourceLoc, funcId, argIndex, tag, ATypeTag.STRING);
- }
- if (argIndex > 0 && argIndex <= 2) {
- switch (tag) {
- case TINYINT:
- case SMALLINT:
- case INTEGER:
- case BIGINT:
- break;
- default:
- throw new TypeMismatchException(sourceLoc, funcId, argIndex, tag, ATypeTag.TINYINT,
- ATypeTag.SMALLINT, ATypeTag.INTEGER, ATypeTag.BIGINT);
- }
- }
- }
-
- @Override
- public IAType getResultType(ILogicalExpression expr, IAType... types) throws AlgebricksException {
- return AUnionType.createNullableType(BuiltinType.ASTRING);
- }
-}
diff --git a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/CodePointToStringDescriptor.java b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/CodePointToStringDescriptor.java
index c4317f9..fcfab72 100644
--- a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/CodePointToStringDescriptor.java
+++ b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/CodePointToStringDescriptor.java
@@ -18,19 +18,23 @@
*/
package org.apache.asterix.runtime.evaluators.functions;
+import static org.apache.asterix.om.types.ATypeTag.BIGINT;
+import static org.apache.asterix.om.types.ATypeTag.MISSING;
+import static org.apache.asterix.om.types.ATypeTag.NULL;
+import static org.apache.asterix.om.types.ATypeTag.VALUE_TYPE_MAPPING;
+
import java.io.DataOutput;
import java.io.IOException;
+import java.util.Arrays;
import org.apache.asterix.common.annotations.MissingNullInOutFunction;
import org.apache.asterix.dataflow.data.nontagged.serde.AOrderedListSerializerDeserializer;
+import org.apache.asterix.om.exceptions.ExceptionUtil;
import org.apache.asterix.om.functions.BuiltinFunctions;
-import org.apache.asterix.om.functions.IFunctionDescriptor;
import org.apache.asterix.om.functions.IFunctionDescriptorFactory;
import org.apache.asterix.om.types.ATypeTag;
import org.apache.asterix.om.types.hierachy.ATypeHierarchy;
import org.apache.asterix.runtime.evaluators.base.AbstractScalarFunctionDynamicDescriptor;
-import org.apache.asterix.runtime.exceptions.TypeMismatchException;
-import org.apache.asterix.runtime.exceptions.UnsupportedTypeException;
import org.apache.hyracks.algebricks.core.algebra.functions.FunctionIdentifier;
import org.apache.hyracks.algebricks.runtime.base.IEvaluatorContext;
import org.apache.hyracks.algebricks.runtime.base.IScalarEvaluator;
@@ -46,12 +50,7 @@
public class CodePointToStringDescriptor extends AbstractScalarFunctionDynamicDescriptor {
private static final long serialVersionUID = 1L;
- public static final IFunctionDescriptorFactory FACTORY = new IFunctionDescriptorFactory() {
- @Override
- public IFunctionDescriptor createFunctionDescriptor() {
- return new CodePointToStringDescriptor();
- }
- };
+ public static final IFunctionDescriptorFactory FACTORY = CodePointToStringDescriptor::new;
@Override
public IScalarEvaluatorFactory createEvaluatorFactory(final IScalarEvaluatorFactory[] args) {
@@ -63,20 +62,21 @@
public IScalarEvaluator createScalarEvaluator(IEvaluatorContext ctx) throws HyracksDataException {
return new IScalarEvaluator() {
- private ArrayBackedValueStorage resultStorage = new ArrayBackedValueStorage();
- private DataOutput out = resultStorage.getDataOutput();
- private IScalarEvaluatorFactory listEvalFactory = args[0];
- private IPointable inputArgList = new VoidPointable();
- private IScalarEvaluator evalList = listEvalFactory.createScalarEvaluator(ctx);
-
+ private final ArrayBackedValueStorage resultStorage = new ArrayBackedValueStorage();
+ private final DataOutput out = resultStorage.getDataOutput();
+ private final IScalarEvaluatorFactory listEvalFactory = args[0];
+ private final IPointable inputArgList = new VoidPointable();
+ private final IScalarEvaluator evalList = listEvalFactory.createScalarEvaluator(ctx);
private final byte[] currentUTF8 = new byte[6];
private final byte[] tempStoreForLength = new byte[5];
- private final byte stringTypeTag = ATypeTag.SERIALIZED_STRING_TYPE_TAG;
+ private final FunctionIdentifier fid = getIdentifier();
@Override
public void evaluate(IFrameTupleReference tuple, IPointable result) throws HyracksDataException {
try {
resultStorage.reset();
+ Arrays.fill(tempStoreForLength, (byte) 0);
+ Arrays.fill(currentUTF8, (byte) 0);
evalList.evaluate(tuple, inputArgList);
if (PointableHelper.checkAndSetMissingOrNull(result, inputArgList)) {
@@ -85,45 +85,63 @@
byte[] serOrderedList = inputArgList.getByteArray();
int offset = inputArgList.getStartOffset();
- int size;
-
- if (ATypeTag.VALUE_TYPE_MAPPING[serOrderedList[offset]] != ATypeTag.ARRAY) {
- throw new TypeMismatchException(sourceLoc, getIdentifier(), 0, serOrderedList[offset]);
- } else {
- switch (ATypeTag.VALUE_TYPE_MAPPING[serOrderedList[offset + 1]]) {
- case TINYINT:
- case SMALLINT:
- case INTEGER:
- case BIGINT:
- case FLOAT:
- case DOUBLE:
- case ANY:
- size = AOrderedListSerializerDeserializer.getNumberOfItems(serOrderedList,
- offset);
- break;
- default:
- throw new UnsupportedTypeException(sourceLoc, getIdentifier(),
- serOrderedList[offset]);
- }
+ if (serOrderedList[offset] != ATypeTag.SERIALIZED_ORDEREDLIST_TYPE_TAG) {
+ PointableHelper.setNull(result);
+ ExceptionUtil.warnTypeMismatch(ctx, sourceLoc, fid, serOrderedList[offset], 0,
+ ATypeTag.ARRAY);
+ return;
}
+ int itemTagPosition = offset + 1;
+ ATypeTag itemTag = VALUE_TYPE_MAPPING[serOrderedList[itemTagPosition]];
+ boolean isItemTagged = itemTag == ATypeTag.ANY;
+ int size = AOrderedListSerializerDeserializer.getNumberOfItems(serOrderedList, offset);
// calculate length first
int utf_8_len = 0;
+ boolean returnNull = false;
+ ATypeTag invalidTag = null;
for (int i = 0; i < size; i++) {
int itemOffset =
AOrderedListSerializerDeserializer.getItemOffset(serOrderedList, offset, i);
- int codePoint = 0;
- codePoint = ATypeHierarchy.getIntegerValueWithDifferentTypeTagPosition(
- getIdentifier().getName(), 0, serOrderedList, itemOffset, offset + 1);
- utf_8_len += UTF8StringUtil.codePointToUTF8(codePoint, currentUTF8);
+ if (isItemTagged) {
+ itemTag = VALUE_TYPE_MAPPING[serOrderedList[itemOffset]];
+ itemTagPosition = itemOffset;
+ itemOffset++;
+ }
+ if (itemTag == MISSING) {
+ PointableHelper.setMissing(result);
+ return;
+ }
+ if (itemTag == NULL) {
+ returnNull = true;
+ invalidTag = null;
+ } else if (!returnNull && !ATypeHierarchy.canPromote(itemTag, BIGINT)) {
+ returnNull = true;
+ invalidTag = itemTag;
+ }
+ if (!returnNull) {
+ int codePoint = ATypeHierarchy.getIntegerValueWithDifferentTypeTagPosition(
+ fid.getName(), 0, serOrderedList, itemOffset, itemTagPosition);
+ utf_8_len += UTF8StringUtil.codePointToUTF8(codePoint, currentUTF8);
+ }
}
- out.writeByte(stringTypeTag);
+ if (returnNull) {
+ PointableHelper.setNull(result);
+ if (invalidTag != null) {
+ ExceptionUtil.warnUnsupportedType(ctx, sourceLoc, fid.getName(), invalidTag);
+ }
+ return;
+ }
+ out.writeByte(ATypeTag.SERIALIZED_STRING_TYPE_TAG);
UTF8StringUtil.writeUTF8Length(utf_8_len, tempStoreForLength, out);
for (int i = 0; i < size; i++) {
int itemOffset =
AOrderedListSerializerDeserializer.getItemOffset(serOrderedList, offset, i);
- int codePoint = 0;
- codePoint = ATypeHierarchy.getIntegerValueWithDifferentTypeTagPosition(
- getIdentifier().getName(), 0, serOrderedList, itemOffset, offset + 1);
+ if (isItemTagged) {
+ itemTagPosition = itemOffset;
+ itemOffset++;
+ }
+ int codePoint = ATypeHierarchy.getIntegerValueWithDifferentTypeTagPosition(
+ fid.getName(), 0, serOrderedList, itemOffset, itemTagPosition);
utf_8_len = UTF8StringUtil.codePointToUTF8(codePoint, currentUTF8);
for (int j = 0; j < utf_8_len; j++) {
out.writeByte(currentUTF8[j]);
@@ -143,5 +161,4 @@
public FunctionIdentifier getIdentifier() {
return BuiltinFunctions.CODEPOINT_TO_STRING;
}
-
}
diff --git a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/StringConcatDescriptor.java b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/StringConcatDescriptor.java
index a3cbfa5..e16ab51 100644
--- a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/StringConcatDescriptor.java
+++ b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/StringConcatDescriptor.java
@@ -25,15 +25,13 @@
import org.apache.asterix.formats.nontagged.SerializerDeserializerProvider;
import org.apache.asterix.om.base.AMissing;
import org.apache.asterix.om.base.ANull;
+import org.apache.asterix.om.exceptions.ExceptionUtil;
import org.apache.asterix.om.functions.BuiltinFunctions;
-import org.apache.asterix.om.functions.IFunctionDescriptor;
import org.apache.asterix.om.functions.IFunctionDescriptorFactory;
import org.apache.asterix.om.types.ATypeTag;
import org.apache.asterix.om.types.BuiltinType;
import org.apache.asterix.runtime.evaluators.base.AbstractScalarFunctionDynamicDescriptor;
import org.apache.asterix.runtime.evaluators.common.ListAccessor;
-import org.apache.asterix.runtime.exceptions.TypeMismatchException;
-import org.apache.asterix.runtime.exceptions.UnsupportedItemTypeException;
import org.apache.hyracks.algebricks.core.algebra.functions.FunctionIdentifier;
import org.apache.hyracks.algebricks.runtime.base.IEvaluatorContext;
import org.apache.hyracks.algebricks.runtime.base.IScalarEvaluator;
@@ -50,12 +48,7 @@
public class StringConcatDescriptor extends AbstractScalarFunctionDynamicDescriptor {
private static final long serialVersionUID = 1L;
- public static final IFunctionDescriptorFactory FACTORY = new IFunctionDescriptorFactory() {
- @Override
- public IFunctionDescriptor createFunctionDescriptor() {
- return new StringConcatDescriptor();
- }
- };
+ public static final IFunctionDescriptorFactory FACTORY = StringConcatDescriptor::new;
@Override
public IScalarEvaluatorFactory createEvaluatorFactory(final IScalarEvaluatorFactory[] args) {
@@ -79,6 +72,8 @@
private ISerializerDeserializer<AMissing> missingSerde =
SerializerDeserializerProvider.INSTANCE.getSerializerDeserializer(BuiltinType.AMISSING);
private final byte[] tempLengthArray = new byte[5];
+ private final byte[] expectedTypes = new byte[] { ATypeTag.SERIALIZED_ORDEREDLIST_TYPE_TAG,
+ ATypeTag.SERIALIZED_UNORDEREDLIST_TYPE_TAG };
@Override
public void evaluate(IFrameTupleReference tuple, IPointable result) throws HyracksDataException {
@@ -95,14 +90,16 @@
if (listBytes[listOffset] != ATypeTag.SERIALIZED_ORDEREDLIST_TYPE_TAG
&& listBytes[listOffset] != ATypeTag.SERIALIZED_UNORDEREDLIST_TYPE_TAG) {
- throw new TypeMismatchException(sourceLoc, getIdentifier(), 0, listBytes[listOffset],
- ATypeTag.SERIALIZED_ORDEREDLIST_TYPE_TAG,
- ATypeTag.SERIALIZED_UNORDEREDLIST_TYPE_TAG);
+ PointableHelper.setNull(result);
+ ExceptionUtil.warnTypeMismatch(ctx, sourceLoc, getIdentifier(), listBytes[listOffset],
+ 0, expectedTypes);
+ return;
}
listAccessor.reset(listBytes, listOffset);
// calculate length first
int utf8Len = 0;
boolean itemIsNull = false;
+ ATypeTag unsupportedType = null;
for (int i = 0; i < listAccessor.size(); i++) {
int itemOffset = listAccessor.getItemOffset(i);
ATypeTag itemType = listAccessor.getItemType(itemOffset);
@@ -121,14 +118,19 @@
result.set(resultStorage);
return;
}
- throw new UnsupportedItemTypeException(sourceLoc, getIdentifier(),
- itemType.serialize());
+ if (unsupportedType == null) {
+ unsupportedType = itemType;
+ }
}
utf8Len += UTF8StringUtil.getUTFLength(listBytes, itemOffset);
}
- if (itemIsNull) {
+ if (itemIsNull || unsupportedType != null) {
nullSerde.serialize(ANull.NULL, out);
result.set(resultStorage);
+ if (unsupportedType != null) {
+ ExceptionUtil.warnUnsupportedType(ctx, sourceLoc, getIdentifier().getName(),
+ unsupportedType);
+ }
return;
}
out.writeByte(ATypeTag.SERIALIZED_STRING_TYPE_TAG);
diff --git a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/SubstringEval.java b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/SubstringEval.java
index 993f5e6..5d8b6ef 100644
--- a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/SubstringEval.java
+++ b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/SubstringEval.java
@@ -22,9 +22,10 @@
import java.io.IOException;
import org.apache.asterix.common.annotations.MissingNullInOutFunction;
+import org.apache.asterix.om.base.AMutableInt32;
+import org.apache.asterix.om.exceptions.ExceptionUtil;
import org.apache.asterix.om.types.ATypeTag;
-import org.apache.asterix.om.types.hierachy.ATypeHierarchy;
-import org.apache.asterix.runtime.exceptions.TypeMismatchException;
+import org.apache.asterix.runtime.evaluators.common.ArgumentUtils;
import org.apache.hyracks.algebricks.core.algebra.functions.FunctionIdentifier;
import org.apache.hyracks.algebricks.runtime.base.IEvaluatorContext;
import org.apache.hyracks.algebricks.runtime.base.IScalarEvaluator;
@@ -44,9 +45,10 @@
private final ArrayBackedValueStorage resultStorage = new ArrayBackedValueStorage();
private final DataOutput out = resultStorage.getDataOutput();
- private IPointable argString = new VoidPointable();
- private IPointable argStart = new VoidPointable();
- private IPointable argLen = new VoidPointable();
+ private final IPointable argString = new VoidPointable();
+ private final IPointable argStart = new VoidPointable();
+ private final IPointable argLen = new VoidPointable();
+ private final IEvaluatorContext ctx;
private final IScalarEvaluator evalString;
private final IScalarEvaluator evalStart;
private final IScalarEvaluator evalLen;
@@ -55,11 +57,12 @@
private final GrowableArray array = new GrowableArray();
private final UTF8StringBuilder builder = new UTF8StringBuilder();
private final UTF8StringPointable string = new UTF8StringPointable();
+ private final AMutableInt32 mutableInt32 = new AMutableInt32(0);
SubstringEval(IEvaluatorContext ctx, IScalarEvaluatorFactory[] args, FunctionIdentifier functionIdentifier,
SourceLocation sourceLoc, int baseOffset) throws HyracksDataException {
super(sourceLoc, functionIdentifier);
-
+ this.ctx = ctx;
evalString = args[0].createScalarEvaluator(ctx);
evalStart = args[1].createScalarEvaluator(ctx);
evalLen = args[2].createScalarEvaluator(ctx);
@@ -80,18 +83,27 @@
byte[] bytes = argStart.getByteArray();
int offset = argStart.getStartOffset();
- int start = ATypeHierarchy.getIntegerValue(functionIdentifier.getName(), 0, bytes, offset);
+ if (!ArgumentUtils.checkWarnOrSetInteger(ctx, sourceLoc, functionIdentifier, 1, bytes, offset, mutableInt32)) {
+ PointableHelper.setNull(result);
+ return;
+ }
+ int start = mutableInt32.getIntegerValue();
bytes = argLen.getByteArray();
offset = argLen.getStartOffset();
- int len = ATypeHierarchy.getIntegerValue(functionIdentifier.getName(), 1, bytes, offset);
+ if (!ArgumentUtils.checkWarnOrSetInteger(ctx, sourceLoc, functionIdentifier, 2, bytes, offset, mutableInt32)) {
+ PointableHelper.setNull(result);
+ return;
+ }
+ int len = mutableInt32.getIntegerValue();
bytes = argString.getByteArray();
offset = argString.getStartOffset();
int length = argString.getLength();
if (bytes[offset] != ATypeTag.SERIALIZED_STRING_TYPE_TAG) {
- throw new TypeMismatchException(sourceLoc, functionIdentifier, 0, bytes[offset],
- ATypeTag.SERIALIZED_STRING_TYPE_TAG);
+ PointableHelper.setNull(result);
+ ExceptionUtil.warnTypeMismatch(ctx, sourceLoc, functionIdentifier, bytes[offset], 0, ATypeTag.STRING);
+ return;
}
string.set(bytes, offset + 1, length - 1);
array.reset();
diff --git a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/binary/BinaryConcatDescriptor.java b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/binary/BinaryConcatDescriptor.java
index 4c6af01..907b591 100644
--- a/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/binary/BinaryConcatDescriptor.java
+++ b/asterixdb/asterix-runtime/src/main/java/org/apache/asterix/runtime/evaluators/functions/binary/BinaryConcatDescriptor.java
@@ -103,6 +103,7 @@
int concatLength = 0;
boolean itemIsNull = false;
for (int i = 0; i < listAccessor.size(); i++) {
+ // TODO(ali): itemOffset should be adjusted if list is heterogeneous like string_concat
int itemOffset = listAccessor.getItemOffset(i);
ATypeTag itemType = listAccessor.getItemType(itemOffset);
if (itemType != ATypeTag.BINARY) {