From 82bcd3903ae2f0e27d58b686971958218b3aab55 Mon Sep 17 00:00:00 2001 From: Masha Basmanova Date: Wed, 17 Jan 2024 00:03:46 -0800 Subject: [PATCH] Fix creation of DuckDB tables with arrays of boolean, tinyint and smallint (#8408) Summary: Creating DuckDB table with a column of type array(boolean), array(tinyint) or array(smallint) having a mix of null and non-null array elements used to fail with ``` INTERNAL Error: Assertion triggered in file "/home/runner/work/velox/velox/_build/debug/_deps/duckdb-src/src/common/types/value.cpp" on line 702: values[i].type() == values[0].type() ``` The problem is that `duckValueAt` template in QueryAssertions.cpp used to convert non-null values by calling duckdb::Value(v) API, which is not defined for bool, int8_t and int16_t. Hence, we ended up calling a version of that API that takes int32_t and returns a value of type INTEGER. However, code for converting null values used duckdb::Value(type) API which takes type directly and therefore creates values of the "right" type. When array value had a mix of null and non-null values we ended up passing a list of elements of different types to DuckDB and hit an assertion. A fix implemented here is to provide explicit overrides for boolean, tinyint and smallint. This issue happens often in join fuzzer runs. Fixes https://github.com/facebookincubator/velox/issues/7943 Pull Request resolved: https://github.com/facebookincubator/velox/pull/8408 Reviewed By: amitkdutta Differential Revision: D52826343 Pulled By: mbasmanova fbshipit-source-id: 41d78f7cde95ed3f8e4b3fe3db980f5b60b52f47 --- velox/exec/tests/utils/QueryAssertions.cpp | 24 ++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/velox/exec/tests/utils/QueryAssertions.cpp b/velox/exec/tests/utils/QueryAssertions.cpp index dfc996e2063b..e224320edaf6 100644 --- a/velox/exec/tests/utils/QueryAssertions.cpp +++ b/velox/exec/tests/utils/QueryAssertions.cpp @@ -39,6 +39,30 @@ ::duckdb::Value duckValueAt(const VectorPtr& vector, vector_size_t index) { return ::duckdb::Value(vector->as>()->valueAt(index)); } +template <> +::duckdb::Value duckValueAt( + const VectorPtr& vector, + vector_size_t index) { + return ::duckdb::Value::TINYINT( + vector->as>()->valueAt(index)); +} + +template <> +::duckdb::Value duckValueAt( + const VectorPtr& vector, + vector_size_t index) { + return ::duckdb::Value::SMALLINT( + vector->as>()->valueAt(index)); +} + +template <> +::duckdb::Value duckValueAt( + const VectorPtr& vector, + vector_size_t index) { + return ::duckdb::Value::BOOLEAN( + vector->as>()->valueAt(index)); +} + template <> ::duckdb::Value duckValueAt( const VectorPtr& vector,