diff --git a/dbms/src/DataTypes/DataTypeAggregateFunction.cpp b/dbms/src/DataTypes/DataTypeAggregateFunction.cpp index 8111b1de2fe..f3b26497912 100644 --- a/dbms/src/DataTypes/DataTypeAggregateFunction.cpp +++ b/dbms/src/DataTypes/DataTypeAggregateFunction.cpp @@ -304,6 +304,10 @@ MutableColumnPtr DataTypeAggregateFunction::createColumn() const return ColumnAggregateFunction::create(function); } +MutableColumnPtr DataTypeAggregateFunction::createColumnWithRandomData(size_t) const +{ + throw Exception("Method createColumnWithRandomData() is not implemented for data type " + getName(), ErrorCodes::NOT_IMPLEMENTED); +} /// Create empty state Field DataTypeAggregateFunction::getDefault() const diff --git a/dbms/src/DataTypes/DataTypeAggregateFunction.h b/dbms/src/DataTypes/DataTypeAggregateFunction.h index 9ae7c67a803..e4c226b2917 100644 --- a/dbms/src/DataTypes/DataTypeAggregateFunction.h +++ b/dbms/src/DataTypes/DataTypeAggregateFunction.h @@ -63,6 +63,7 @@ public: void deserializeProtobuf(IColumn & column, ProtobufReader & protobuf, bool allow_add_row, bool & row_added) const override; MutableColumnPtr createColumn() const override; + MutableColumnPtr createColumnWithRandomData(size_t) const override; Field getDefault() const override; diff --git a/dbms/src/DataTypes/DataTypeArray.cpp b/dbms/src/DataTypes/DataTypeArray.cpp index e2c03805ea8..0500182c61a 100644 --- a/dbms/src/DataTypes/DataTypeArray.cpp +++ b/dbms/src/DataTypes/DataTypeArray.cpp @@ -487,6 +487,13 @@ MutableColumnPtr DataTypeArray::createColumn() const } +MutableColumnPtr DataTypeArray::createColumnWithRandomData(size_t limit) const +{ + (void)limit; + throw Exception("Method createColumnWithRandomData() is not implemented for data type " + getName(), ErrorCodes::NOT_IMPLEMENTED); +} + + Field DataTypeArray::getDefault() const { return Array(); diff --git a/dbms/src/DataTypes/DataTypeArray.h b/dbms/src/DataTypes/DataTypeArray.h index 1451f27dfbe..ccf269bd357 100644 --- a/dbms/src/DataTypes/DataTypeArray.h +++ b/dbms/src/DataTypes/DataTypeArray.h @@ -94,6 +94,7 @@ public: bool & row_added) const override; MutableColumnPtr createColumn() const override; + MutableColumnPtr createColumnWithRandomData(size_t) const override; Field getDefault() const override; diff --git a/dbms/src/DataTypes/DataTypeDecimalBase.cpp b/dbms/src/DataTypes/DataTypeDecimalBase.cpp index 7b9a391427c..a0f2bd7bd82 100644 --- a/dbms/src/DataTypes/DataTypeDecimalBase.cpp +++ b/dbms/src/DataTypes/DataTypeDecimalBase.cpp @@ -41,6 +41,13 @@ MutableColumnPtr DataTypeDecimalBase::createColumn() const return ColumnType::create(0, scale); } +template +MutableColumnPtr DataTypeDecimalBase::createColumnWithRandomData(size_t limit) const +{ + (void)limit; + throw Exception("Method createColumnWithRandomData() is not implemented for data type " + getName(), ErrorCodes::NOT_IMPLEMENTED); +} + template void DataTypeDecimalBase::serializeBinary(const Field & field, WriteBuffer & ostr) const { diff --git a/dbms/src/DataTypes/DataTypeDecimalBase.h b/dbms/src/DataTypes/DataTypeDecimalBase.h index 11f7490e80a..d579b965412 100644 --- a/dbms/src/DataTypes/DataTypeDecimalBase.h +++ b/dbms/src/DataTypes/DataTypeDecimalBase.h @@ -83,6 +83,7 @@ public: Field getDefault() const override; MutableColumnPtr createColumn() const override; + MutableColumnPtr createColumnWithRandomData(size_t) const override; bool isParametric() const override { return true; } bool haveSubtypes() const override { return false; } diff --git a/dbms/src/DataTypes/DataTypeEnum.h b/dbms/src/DataTypes/DataTypeEnum.h index 2cb677984df..a0408df0279 100644 --- a/dbms/src/DataTypes/DataTypeEnum.h +++ b/dbms/src/DataTypes/DataTypeEnum.h @@ -111,6 +111,7 @@ public: void deserializeProtobuf(IColumn & column, ProtobufReader & protobuf, bool allow_add_row, bool & row_added) const override; MutableColumnPtr createColumn() const override { return ColumnType::create(); } + MutableColumnPtr createColumnWithRandomData(size_t) const override; Field getDefault() const override; void insertDefaultInto(IColumn & column) const override; diff --git a/dbms/src/DataTypes/DataTypeFixedString.cpp b/dbms/src/DataTypes/DataTypeFixedString.cpp index d30f1003ca0..a148d0b2d22 100644 --- a/dbms/src/DataTypes/DataTypeFixedString.cpp +++ b/dbms/src/DataTypes/DataTypeFixedString.cpp @@ -268,6 +268,12 @@ MutableColumnPtr DataTypeFixedString::createColumn() const return ColumnFixedString::create(n); } +MutableColumnPtr DataTypeFixedString::createColumnWithRandomData(size_t limit) const +{ + (void)limit; + throw Exception("Method createColumnWithRandomData() is not implemented for data type " + getName(), ErrorCodes::NOT_IMPLEMENTED); +} + Field DataTypeFixedString::getDefault() const { return String(); diff --git a/dbms/src/DataTypes/DataTypeFixedString.h b/dbms/src/DataTypes/DataTypeFixedString.h index 6d1f1c4db83..4f264d3ac86 100644 --- a/dbms/src/DataTypes/DataTypeFixedString.h +++ b/dbms/src/DataTypes/DataTypeFixedString.h @@ -70,6 +70,7 @@ public: void deserializeProtobuf(IColumn & column, ProtobufReader & protobuf, bool allow_add_row, bool & row_added) const override; MutableColumnPtr createColumn() const override; + MutableColumnPtr createColumnWithRandomData(size_t) const override; Field getDefault() const override; diff --git a/dbms/src/DataTypes/DataTypeLowCardinality.cpp b/dbms/src/DataTypes/DataTypeLowCardinality.cpp index 5db32bd5380..24dc3af48c9 100644 --- a/dbms/src/DataTypes/DataTypeLowCardinality.cpp +++ b/dbms/src/DataTypes/DataTypeLowCardinality.cpp @@ -934,6 +934,12 @@ MutableColumnPtr DataTypeLowCardinality::createColumn() const return ColumnLowCardinality::create(std::move(dictionary), std::move(indexes)); } +MutableColumnPtr DataTypeLowCardinality::createColumnWithRandomData(size_t limit) const +{ + (void)limit; + throw Exception("Method createColumnWithRandomData() is not implemented for data type " + getName(), ErrorCodes::NOT_IMPLEMENTED); +} + Field DataTypeLowCardinality::getDefault() const { return dictionary_type->getDefault(); diff --git a/dbms/src/DataTypes/DataTypeLowCardinality.h b/dbms/src/DataTypes/DataTypeLowCardinality.h index f8c314909b8..9b22acea7e3 100644 --- a/dbms/src/DataTypes/DataTypeLowCardinality.h +++ b/dbms/src/DataTypes/DataTypeLowCardinality.h @@ -68,6 +68,7 @@ public: void deserializeProtobuf(IColumn & column, ProtobufReader & protobuf, bool allow_add_row, bool & row_added) const override; MutableColumnPtr createColumn() const override; + MutableColumnPtr createColumnWithRandomData(size_t) const override; Field getDefault() const override; diff --git a/dbms/src/DataTypes/DataTypeNothing.cpp b/dbms/src/DataTypes/DataTypeNothing.cpp index 79fbb002bff..ce4990748f9 100644 --- a/dbms/src/DataTypes/DataTypeNothing.cpp +++ b/dbms/src/DataTypes/DataTypeNothing.cpp @@ -14,6 +14,14 @@ MutableColumnPtr DataTypeNothing::createColumn() const return ColumnNothing::create(0); } + +MutableColumnPtr DataTypeNothing::createColumnWithRandomData(size_t limit) const +{ + (void)limit; + throw Exception("Method createColumnWithRandomData() is not implemented for data type " + getName(), ErrorCodes::NOT_IMPLEMENTED); +} + + void DataTypeNothing::serializeBinaryBulk(const IColumn & column, WriteBuffer & ostr, size_t offset, size_t limit) const { size_t size = column.size(); diff --git a/dbms/src/DataTypes/DataTypeNothing.h b/dbms/src/DataTypes/DataTypeNothing.h index e9421fb15e8..5fbe0acc0a9 100644 --- a/dbms/src/DataTypes/DataTypeNothing.h +++ b/dbms/src/DataTypes/DataTypeNothing.h @@ -19,6 +19,7 @@ public: TypeIndex getTypeId() const override { return TypeIndex::Nothing; } MutableColumnPtr createColumn() const override; + MutableColumnPtr createColumnWithRandomData(size_t) const override; /// These methods read and write zero bytes just to allow to figure out size of column. void serializeBinaryBulk(const IColumn & column, WriteBuffer & ostr, size_t offset, size_t limit) const override; diff --git a/dbms/src/DataTypes/DataTypeNullable.cpp b/dbms/src/DataTypes/DataTypeNullable.cpp index 397d5ba0a65..6f31e66a1e5 100644 --- a/dbms/src/DataTypes/DataTypeNullable.cpp +++ b/dbms/src/DataTypes/DataTypeNullable.cpp @@ -488,6 +488,11 @@ MutableColumnPtr DataTypeNullable::createColumn() const return ColumnNullable::create(nested_data_type->createColumn(), ColumnUInt8::create()); } +MutableColumnPtr DataTypeNullable::createColumnWithRandomData(size_t limit) const +{ + return ColumnNullable::create(nested_data_type->createColumnWithRandomData(limit), DataTypeUInt8().createColumnWithRandomData(limit)); +} + Field DataTypeNullable::getDefault() const { return Null(); diff --git a/dbms/src/DataTypes/DataTypeNullable.h b/dbms/src/DataTypes/DataTypeNullable.h index 1766b399c2a..83a76ae0410 100644 --- a/dbms/src/DataTypes/DataTypeNullable.h +++ b/dbms/src/DataTypes/DataTypeNullable.h @@ -76,6 +76,7 @@ public: void deserializeProtobuf(IColumn & column, ProtobufReader & protobuf, bool allow_add_row, bool & row_added) const override; MutableColumnPtr createColumn() const override; + MutableColumnPtr createColumnWithRandomData(size_t) const override; Field getDefault() const override; diff --git a/dbms/src/DataTypes/DataTypeNumberBase.cpp b/dbms/src/DataTypes/DataTypeNumberBase.cpp index 90356817730..937967d431a 100644 --- a/dbms/src/DataTypes/DataTypeNumberBase.cpp +++ b/dbms/src/DataTypes/DataTypeNumberBase.cpp @@ -239,6 +239,13 @@ MutableColumnPtr DataTypeNumberBase::createColumn() const return ColumnVector::create(); } +template +MutableColumnPtr DataTypeNumberBase::createColumnWithRandomData(size_t limit) const +{ + (void)limit; + throw Exception("Method createColumnWithRandomData() is not implemented for data type " + getName(), ErrorCodes::NOT_IMPLEMENTED); +} + template bool DataTypeNumberBase::isValueRepresentedByInteger() const { diff --git a/dbms/src/DataTypes/DataTypeNumberBase.h b/dbms/src/DataTypes/DataTypeNumberBase.h index fb752ad5329..5a3dda5fe15 100644 --- a/dbms/src/DataTypes/DataTypeNumberBase.h +++ b/dbms/src/DataTypes/DataTypeNumberBase.h @@ -45,6 +45,7 @@ public: void deserializeProtobuf(IColumn & column, ProtobufReader & protobuf, bool allow_add_row, bool & row_added) const override; MutableColumnPtr createColumn() const override; + MutableColumnPtr createColumnWithRandomData(size_t) const override; bool isParametric() const override { return false; } bool haveSubtypes() const override { return false; } diff --git a/dbms/src/DataTypes/DataTypeSet.h b/dbms/src/DataTypes/DataTypeSet.h index 7ef0d931279..1d0d56c164b 100644 --- a/dbms/src/DataTypes/DataTypeSet.h +++ b/dbms/src/DataTypes/DataTypeSet.h @@ -21,6 +21,7 @@ public: // Used for expressions analysis. MutableColumnPtr createColumn() const override { return ColumnSet::create(0, nullptr); } + MutableColumnPtr createColumnWithRandomData(size_t) const override; // Used only for debugging, making it DUMPABLE Field getDefault() const override { return Tuple(); } diff --git a/dbms/src/DataTypes/DataTypeString.cpp b/dbms/src/DataTypes/DataTypeString.cpp index ef32fe33690..46478396a68 100644 --- a/dbms/src/DataTypes/DataTypeString.cpp +++ b/dbms/src/DataTypes/DataTypeString.cpp @@ -360,6 +360,11 @@ MutableColumnPtr DataTypeString::createColumn() const return ColumnString::create(); } +MutableColumnPtr DataTypeString::createColumnWithRandomData(size_t limit) const +{ + (void)limit; + throw Exception("Method createColumnWithRandomData() is not implemented for data type " + getName(), ErrorCodes::NOT_IMPLEMENTED); +} bool DataTypeString::equals(const IDataType & rhs) const { diff --git a/dbms/src/DataTypes/DataTypeString.h b/dbms/src/DataTypes/DataTypeString.h index 28968eef3f1..4a2c6be42e1 100644 --- a/dbms/src/DataTypes/DataTypeString.h +++ b/dbms/src/DataTypes/DataTypeString.h @@ -54,6 +54,7 @@ public: void deserializeProtobuf(IColumn & column, ProtobufReader & protobuf, bool allow_add_row, bool & row_added) const override; MutableColumnPtr createColumn() const override; + MutableColumnPtr createColumnWithRandomData(size_t) const override; Field getDefault() const override; diff --git a/dbms/src/DataTypes/DataTypeTuple.cpp b/dbms/src/DataTypes/DataTypeTuple.cpp index 4d60177aa4d..5c912b89f2d 100644 --- a/dbms/src/DataTypes/DataTypeTuple.cpp +++ b/dbms/src/DataTypes/DataTypeTuple.cpp @@ -454,6 +454,14 @@ MutableColumnPtr DataTypeTuple::createColumn() const return ColumnTuple::create(std::move(tuple_columns)); } + +MutableColumnPtr DataTypeTuple::createColumnWithRandomData(size_t limit) const +{ + (void)limit; + throw Exception("Method createColumnWithRandomData() is not implemented for data type " + getName(), ErrorCodes::NOT_IMPLEMENTED); +} + + Field DataTypeTuple::getDefault() const { return Tuple(ext::map(elems, [] (const DataTypePtr & elem) { return elem->getDefault(); })); diff --git a/dbms/src/DataTypes/DataTypeTuple.h b/dbms/src/DataTypes/DataTypeTuple.h index 06f0f62026e..a3a8fb2847e 100644 --- a/dbms/src/DataTypes/DataTypeTuple.h +++ b/dbms/src/DataTypes/DataTypeTuple.h @@ -81,6 +81,7 @@ public: void deserializeProtobuf(IColumn & column, ProtobufReader & reader, bool allow_add_row, bool & row_added) const override; MutableColumnPtr createColumn() const override; + MutableColumnPtr createColumnWithRandomData(size_t) const override; Field getDefault() const override; void insertDefaultInto(IColumn & column) const override; diff --git a/dbms/src/DataTypes/IDataType.h b/dbms/src/DataTypes/IDataType.h index 92d0c1057c5..04ad5896154 100644 --- a/dbms/src/DataTypes/IDataType.h +++ b/dbms/src/DataTypes/IDataType.h @@ -287,6 +287,10 @@ public: */ virtual MutableColumnPtr createColumn() const = 0; + /** Create column for corresponding type and fill with random values. + */ + virtual MutableColumnPtr createColumnWithRandomData(size_t size) const = 0; + /** Create ColumnConst for corresponding type, with specified size and value. */ ColumnPtr createColumnConst(size_t size, const Field & field) const; diff --git a/dbms/src/DataTypes/IDataTypeDummy.h b/dbms/src/DataTypes/IDataTypeDummy.h index f27359e5f74..e346689274f 100644 --- a/dbms/src/DataTypes/IDataTypeDummy.h +++ b/dbms/src/DataTypes/IDataTypeDummy.h @@ -42,6 +42,11 @@ public: throw Exception("Method createColumn() is not implemented for data type " + getName(), ErrorCodes::NOT_IMPLEMENTED); } + MutableColumnPtr createColumnWithRandomData(size_t) const override + { + throw Exception("Method createColumnWithRandomData() is not implemented for data type " + getName(), ErrorCodes::NOT_IMPLEMENTED); + } + Field getDefault() const override { throw Exception("Method getDefault() is not implemented for data type " + getName(), ErrorCodes::NOT_IMPLEMENTED); diff --git a/dbms/src/TableFunctions/TableFunctionRandom.cpp b/dbms/src/TableFunctions/TableFunctionRandom.cpp new file mode 100644 index 00000000000..f7ffe977698 --- /dev/null +++ b/dbms/src/TableFunctions/TableFunctionRandom.cpp @@ -0,0 +1,69 @@ +#include +#include + +#include +#include +#include + +#include +#include +#include + +#include +#include +#include + +#include "registerTableFunctions.h" + + +namespace DB +{ + +namespace ErrorCodes +{ + extern const int NUMBER_OF_ARGUMENTS_DOESNT_MATCH; + extern const int BAD_ARGUMENTS; +} + +StoragePtr TableFunctionRandom::executeImpl(const ASTPtr & ast_function, const Context & context, const std::string & table_name) const +{ + ASTs & args_func = ast_function->children; + + if (args_func.size() != 1) + throw Exception("Table function '" + getName() + "' must have arguments.", ErrorCodes::LOGICAL_ERROR); + + ASTs & args = args_func.at(0)->children; + + if (args.size() > 2) + throw Exception("Table function '" + getName() + "' requires one or two arguments: structure (and limit).", + ErrorCodes::NUMBER_OF_ARGUMENTS_DOESNT_MATCH); + + /// Parsing first argument as table structure and creating a sample block + std::string structure = args[0]->as().value.safeGet(); + + UInt64 limit = 1; + /// Parsing second argument if present + if (args.size() == 2) + limit = args[1]->as().value.safeGet(); + + if (!limit) + throw Exception("Table function '" + getName() + "' limit should not be 0.", ErrorCodes::BAD_ARGUMENTS); + + ColumnsDescription columns = parseColumnsListFromString(structure, context); + + Block res_block; + for (const auto & name_type : columns.getOrdinary()) + Column c = name_type.type->createColumnWithRandomData(limit) ; + res_block.insert({ c, name_type.type, name_type.name }); + + auto res = StorageValues::create(StorageID(getDatabaseName(), table_name), columns, res_block); + res->startup(); + return res; +} + +void registerTableFunctionRandom(TableFunctionFactory & factory) +{ + factory.registerFunction(TableFunctionFactory::CaseInsensitive); +} + +} diff --git a/dbms/src/TableFunctions/TableFunctionRandom.h b/dbms/src/TableFunctions/TableFunctionRandom.h new file mode 100644 index 00000000000..c4f8e2bca37 --- /dev/null +++ b/dbms/src/TableFunctions/TableFunctionRandom.h @@ -0,0 +1,20 @@ +#pragma once + +#include + +namespace DB +{ +/* random(structure, limit) - creates a temporary storage filling columns with random data + * random is case-insensitive table function + */ +class TableFunctionRandom : public ITableFunction +{ +public: + static constexpr auto name = "generate"; + std::string getName() const override { return name; } +private: + StoragePtr executeImpl(const ASTPtr & ast_function, const Context & context, const std::string & table_name) const override; +}; + + +} diff --git a/dbms/src/TableFunctions/registerTableFunctions.cpp b/dbms/src/TableFunctions/registerTableFunctions.cpp index 35021cd46d0..91b6b94440c 100644 --- a/dbms/src/TableFunctions/registerTableFunctions.cpp +++ b/dbms/src/TableFunctions/registerTableFunctions.cpp @@ -15,6 +15,7 @@ void registerTableFunctions() registerTableFunctionURL(factory); registerTableFunctionValues(factory); registerTableFunctionInput(factory); + registerTableFunctionRandom(factory); #if USE_AWS_S3 registerTableFunctionS3(factory); diff --git a/dbms/src/TableFunctions/registerTableFunctions.h b/dbms/src/TableFunctions/registerTableFunctions.h index 66f2dda90ea..8ae5ab339f4 100644 --- a/dbms/src/TableFunctions/registerTableFunctions.h +++ b/dbms/src/TableFunctions/registerTableFunctions.h @@ -12,6 +12,7 @@ void registerTableFunctionFile(TableFunctionFactory & factory); void registerTableFunctionURL(TableFunctionFactory & factory); void registerTableFunctionValues(TableFunctionFactory & factory); void registerTableFunctionInput(TableFunctionFactory & factory); +void registerTableFunctionRandom(TableFunctionFactory & factory); #if USE_AWS_S3 void registerTableFunctionS3(TableFunctionFactory & factory); diff --git a/dbms/tests/queries/0_stateless/01072_random_table_function.sql b/dbms/tests/queries/0_stateless/01072_random_table_function.sql new file mode 100644 index 00000000000..fb217befea5 --- /dev/null +++ b/dbms/tests/queries/0_stateless/01072_random_table_function.sql @@ -0,0 +1 @@ +SELECT * FROM random(3)