From d59b0d7ec0633822a3e20f6c2d5f99c743117f63 Mon Sep 17 00:00:00 2001 From: pyos Date: Wed, 25 Apr 2018 18:16:48 +0300 Subject: [PATCH] Add IColumn::getRawData to fixed-contiguous columns --- dbms/src/Columns/ColumnConst.h | 1 + dbms/src/Columns/ColumnFixedString.h | 2 +- dbms/src/Columns/ColumnVector.h | 2 +- dbms/src/Columns/IColumn.h | 3 ++ dbms/src/Interpreters/ExpressionJIT.cpp | 45 +++++++++++-------------- 5 files changed, 25 insertions(+), 28 deletions(-) diff --git a/dbms/src/Columns/ColumnConst.h b/dbms/src/Columns/ColumnConst.h index 2e4a692451f..7631917da76 100644 --- a/dbms/src/Columns/ColumnConst.h +++ b/dbms/src/Columns/ColumnConst.h @@ -188,6 +188,7 @@ public: bool isFixedAndContiguous() const override { return data->isFixedAndContiguous(); } bool valuesHaveFixedSize() const override { return data->valuesHaveFixedSize(); } size_t sizeOfValueIfFixed() const override { return data->sizeOfValueIfFixed(); } + StringRef getRawData() const override { return data->getRawData(); } /// Not part of the common interface. diff --git a/dbms/src/Columns/ColumnFixedString.h b/dbms/src/Columns/ColumnFixedString.h index cd465a1814d..80b6ccd5456 100644 --- a/dbms/src/Columns/ColumnFixedString.h +++ b/dbms/src/Columns/ColumnFixedString.h @@ -129,7 +129,7 @@ public: bool isFixedAndContiguous() const override { return true; } size_t sizeOfValueIfFixed() const override { return n; } - + StringRef getRawData() const override { return StringRef(chars.data(), chars.size()); } /// Specialized part of interface, not from IColumn. diff --git a/dbms/src/Columns/ColumnVector.h b/dbms/src/Columns/ColumnVector.h index 5ce33e82028..ec940300c81 100644 --- a/dbms/src/Columns/ColumnVector.h +++ b/dbms/src/Columns/ColumnVector.h @@ -263,7 +263,7 @@ public: bool isFixedAndContiguous() const override { return true; } size_t sizeOfValueIfFixed() const override { return sizeof(T); } - + StringRef getRawData() const override { return StringRef(reinterpret_cast(data.data()), data.size()); } /** More efficient methods of manipulation - to manipulate with data directly. */ Container & getData() diff --git a/dbms/src/Columns/IColumn.h b/dbms/src/Columns/IColumn.h index 40577a11d3f..c69e47f9c7f 100644 --- a/dbms/src/Columns/IColumn.h +++ b/dbms/src/Columns/IColumn.h @@ -298,6 +298,9 @@ public: /// Values in column are represented as continuous memory segment of fixed size. Implies valuesHaveFixedSize. virtual bool isFixedAndContiguous() const { return false; } + /// If isFixedAndContiguous, returns the underlying data array, otherwise throws an exception. + virtual StringRef getRawData() const { throw Exception("Column " + getName() + " is not a contiguous block of memory", ErrorCodes::NOT_IMPLEMENTED); } + /// If valuesHaveFixedSize, returns size of value, otherwise throw an exception. virtual size_t sizeOfValueIfFixed() const { throw Exception("Values of column " + getName() + " are not fixed size.", ErrorCodes::CANNOT_GET_SIZE_OF_FIELD); } diff --git a/dbms/src/Interpreters/ExpressionJIT.cpp b/dbms/src/Interpreters/ExpressionJIT.cpp index f6f523c3c37..7340b511fe2 100644 --- a/dbms/src/Interpreters/ExpressionJIT.cpp +++ b/dbms/src/Interpreters/ExpressionJIT.cpp @@ -40,9 +40,7 @@ namespace ErrorCodes template static bool typeIsA(const DataTypePtr & type) { - if (auto * nullable = typeid_cast(type.get())) - return typeIsA(nullable->getNestedType()); - return typeid_cast(type.get());; + return typeid_cast(removeNullable(type).get());; } struct LLVMContext::Data @@ -128,33 +126,28 @@ LLVMPreparedFunction::LLVMPreparedFunction(LLVMContext context, std::shared_ptr< : parent(parent), context(context), function(context->lookup(parent->getName())) {} -static MutableColumnPtr createNonNullableColumn(const DataTypePtr & type) -{ - if (auto * nullable = typeid_cast(type.get())) - return createNonNullableColumn(nullable->getNestedType()); - return type->createColumn(); -} - void LLVMPreparedFunction::executeImpl(Block & block, const ColumnNumbers & arguments, size_t result) { - size_t block_size = 0; - std::vector columns(arguments.size()); - std::vector is_const(arguments.size()); - for (size_t i = 0; i < arguments.size(); i++) - { - auto * column = block.getByPosition(arguments[i]).column.get(); - if (column->size()) - /// assume the column is a `ColumnVector`. there's probably no good way to actually - /// check that at runtime, so let's just hope it's always true for columns containing types - /// for which `LLVMContext::Data::toNativeType` returns non-null. - columns[i] = column->getDataAt(0).data; - is_const[i] = column->isColumnConst(); - block_size = column->size(); - } /// assuming that the function has default behavior on NULL, the column will be wrapped by `PreparedFunctionImpl::execute`. - auto col_res = createNonNullableColumn(parent->getReturnType())->cloneResized(block_size); + size_t block_size = block.rows(); + auto col_res = removeNullable(parent->getReturnType())->createColumn()->cloneResized(block_size); if (block_size) - function(columns.data(), is_const.data(), const_cast(col_res->getDataAt(0).data), block_size); + { + std::vector columns(arguments.size()); + std::vector is_const(arguments.size()); + for (size_t i = 0; i < arguments.size(); i++) + { + auto * column = block.getByPosition(arguments[i]).column.get(); + if (!column) + throw Exception("column " + block.getByPosition(arguments[i]).name + " is missing", ErrorCodes::LOGICAL_ERROR); + if (!column->isFixedAndContiguous()) + throw Exception("column type " + column->getName() + " is not a contiguous array; its data type " + "should've had no native equivalent in LLVMContext::Data::toNativeType", ErrorCodes::LOGICAL_ERROR); + columns[i] = column->getRawData().data; + is_const[i] = column->isColumnConst(); + } + function(columns.data(), is_const.data(), const_cast(col_res->getRawData().data), block_size); + } block.getByPosition(result).column = std::move(col_res); };