mirror of
https://github.com/ClickHouse/ClickHouse.git
synced 2024-10-05 16:10:50 +00:00
Merge
This commit is contained in:
commit
95bef85dd2
@ -2,6 +2,8 @@
|
|||||||
|
|
||||||
#include <stats/ReservoirSampler.h>
|
#include <stats/ReservoirSampler.h>
|
||||||
|
|
||||||
|
#include <DB/Core/FieldVisitors.h>
|
||||||
|
|
||||||
#include <DB/IO/WriteHelpers.h>
|
#include <DB/IO/WriteHelpers.h>
|
||||||
#include <DB/IO/ReadHelpers.h>
|
#include <DB/IO/ReadHelpers.h>
|
||||||
|
|
||||||
|
@ -2,6 +2,8 @@
|
|||||||
|
|
||||||
#include <DB/AggregateFunctions/ReservoirSamplerDeterministic.h>
|
#include <DB/AggregateFunctions/ReservoirSamplerDeterministic.h>
|
||||||
|
|
||||||
|
#include <DB/Core/FieldVisitors.h>
|
||||||
|
|
||||||
#include <DB/IO/WriteHelpers.h>
|
#include <DB/IO/WriteHelpers.h>
|
||||||
#include <DB/IO/ReadHelpers.h>
|
#include <DB/IO/ReadHelpers.h>
|
||||||
|
|
||||||
|
@ -4,6 +4,8 @@
|
|||||||
|
|
||||||
#include <DB/Common/MemoryTracker.h>
|
#include <DB/Common/MemoryTracker.h>
|
||||||
|
|
||||||
|
#include <DB/Core/FieldVisitors.h>
|
||||||
|
|
||||||
#include <DB/IO/WriteHelpers.h>
|
#include <DB/IO/WriteHelpers.h>
|
||||||
#include <DB/IO/ReadHelpers.h>
|
#include <DB/IO/ReadHelpers.h>
|
||||||
|
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include <DB/Core/FieldVisitors.h>
|
||||||
#include <DB/AggregateFunctions/IUnaryAggregateFunction.h>
|
#include <DB/AggregateFunctions/IUnaryAggregateFunction.h>
|
||||||
#include <DB/DataTypes/DataTypesNumberFixed.h>
|
#include <DB/DataTypes/DataTypesNumberFixed.h>
|
||||||
|
|
||||||
|
@ -9,6 +9,9 @@
|
|||||||
#include <DB/Core/Field.h>
|
#include <DB/Core/Field.h>
|
||||||
|
|
||||||
#include <DB/IO/ReadBufferFromString.h>
|
#include <DB/IO/ReadBufferFromString.h>
|
||||||
|
#include <DB/IO/WriteBuffer.h>
|
||||||
|
#include <DB/IO/WriteHelpers.h>
|
||||||
|
|
||||||
|
|
||||||
namespace DB
|
namespace DB
|
||||||
{
|
{
|
||||||
|
@ -6,6 +6,9 @@
|
|||||||
#include <DB/Core/ErrorCodes.h>
|
#include <DB/Core/ErrorCodes.h>
|
||||||
#include <DB/Common/Arena.h>
|
#include <DB/Common/Arena.h>
|
||||||
|
|
||||||
|
#include <DB/IO/WriteBuffer.h>
|
||||||
|
#include <DB/IO/WriteHelpers.h>
|
||||||
|
|
||||||
#include <DB/Columns/IColumn.h>
|
#include <DB/Columns/IColumn.h>
|
||||||
|
|
||||||
|
|
||||||
|
@ -11,8 +11,6 @@
|
|||||||
#include <Poco/Mutex.h>
|
#include <Poco/Mutex.h>
|
||||||
#include <Poco/ScopedLock.h>
|
#include <Poco/ScopedLock.h>
|
||||||
|
|
||||||
#include <boost/function.hpp>
|
|
||||||
|
|
||||||
#include <DB/Common/Exception.h>
|
#include <DB/Common/Exception.h>
|
||||||
#include <DB/IO/ReadBufferFromFileDescriptor.h>
|
#include <DB/IO/ReadBufferFromFileDescriptor.h>
|
||||||
#include <DB/IO/WriteBufferFromFileDescriptor.h>
|
#include <DB/IO/WriteBufferFromFileDescriptor.h>
|
||||||
|
@ -294,6 +294,7 @@ namespace ErrorCodes
|
|||||||
LIMIT_EXCEEDED = 290,
|
LIMIT_EXCEEDED = 290,
|
||||||
DATABASE_ACCESS_DENIED = 291,
|
DATABASE_ACCESS_DENIED = 291,
|
||||||
LEADERSHIP_CHANGED = 292,
|
LEADERSHIP_CHANGED = 292,
|
||||||
|
MONGODB_INIT_FAILED = 293,
|
||||||
|
|
||||||
KEEPER_EXCEPTION = 999,
|
KEEPER_EXCEPTION = 999,
|
||||||
POCO_EXCEPTION = 1000,
|
POCO_EXCEPTION = 1000,
|
||||||
|
@ -6,18 +6,9 @@
|
|||||||
|
|
||||||
#include <boost/static_assert.hpp>
|
#include <boost/static_assert.hpp>
|
||||||
|
|
||||||
#include <mysqlxx/Date.h>
|
|
||||||
#include <mysqlxx/DateTime.h>
|
|
||||||
#include <mysqlxx/Manip.h>
|
|
||||||
|
|
||||||
#include <DB/Core/Types.h>
|
|
||||||
#include <DB/Common/Exception.h>
|
#include <DB/Common/Exception.h>
|
||||||
#include <DB/Core/ErrorCodes.h>
|
#include <DB/Core/ErrorCodes.h>
|
||||||
#include <DB/IO/ReadHelpers.h>
|
#include <DB/Core/Types.h>
|
||||||
#include <DB/IO/WriteHelpers.h>
|
|
||||||
#include <DB/IO/WriteBufferFromString.h>
|
|
||||||
|
|
||||||
#include <DB/IO/DoubleConverter.h>
|
|
||||||
|
|
||||||
|
|
||||||
namespace DB
|
namespace DB
|
||||||
@ -342,6 +333,8 @@ private:
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#undef DBMS_TOTAL_FIELD_SIZE
|
||||||
|
|
||||||
|
|
||||||
template <> struct Field::TypeToEnum<Null> { static const Types::Which value = Types::Null; };
|
template <> struct Field::TypeToEnum<Null> { static const Types::Which value = Types::Null; };
|
||||||
template <> struct Field::TypeToEnum<UInt64> { static const Types::Which value = Types::UInt64; };
|
template <> struct Field::TypeToEnum<UInt64> { static const Types::Which value = Types::UInt64; };
|
||||||
@ -383,280 +376,9 @@ T safeGet(Field & field)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/** StaticVisitor (его наследники) - класс с перегруженными для разных типов операторами ().
|
|
||||||
* Вызвать visitor для field можно с помощью функции apply_visitor.
|
|
||||||
* Также поддерживается visitor, в котором оператор () принимает два аргумента.
|
|
||||||
*/
|
|
||||||
template <typename R = void>
|
|
||||||
struct StaticVisitor
|
|
||||||
{
|
|
||||||
typedef R ResultType;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
template <typename Visitor, typename F>
|
|
||||||
typename Visitor::ResultType apply_visitor_impl(Visitor & visitor, F & field)
|
|
||||||
{
|
|
||||||
switch (field.getType())
|
|
||||||
{
|
|
||||||
case Field::Types::Null: return visitor(field.template get<Null>());
|
|
||||||
case Field::Types::UInt64: return visitor(field.template get<UInt64>());
|
|
||||||
case Field::Types::Int64: return visitor(field.template get<Int64>());
|
|
||||||
case Field::Types::Float64: return visitor(field.template get<Float64>());
|
|
||||||
case Field::Types::String: return visitor(field.template get<String>());
|
|
||||||
case Field::Types::Array: return visitor(field.template get<Array>());
|
|
||||||
|
|
||||||
default:
|
|
||||||
throw Exception("Bad type of Field", ErrorCodes::BAD_TYPE_OF_FIELD);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Эти штуки нужны, чтобы принимать временный объект по константной ссылке.
|
|
||||||
* В шаблон выше, типы форвардятся уже с const-ом.
|
|
||||||
*/
|
|
||||||
|
|
||||||
template <typename Visitor>
|
|
||||||
typename Visitor::ResultType apply_visitor(const Visitor & visitor, Field & field)
|
|
||||||
{
|
|
||||||
return apply_visitor_impl(visitor, field);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename Visitor>
|
|
||||||
typename Visitor::ResultType apply_visitor(const Visitor & visitor, const Field & field)
|
|
||||||
{
|
|
||||||
return apply_visitor_impl(visitor, field);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename Visitor>
|
|
||||||
typename Visitor::ResultType apply_visitor(Visitor & visitor, Field & field)
|
|
||||||
{
|
|
||||||
return apply_visitor_impl(visitor, field);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename Visitor>
|
|
||||||
typename Visitor::ResultType apply_visitor(Visitor & visitor, const Field & field)
|
|
||||||
{
|
|
||||||
return apply_visitor_impl(visitor, field);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
template <typename Visitor, typename F1, typename F2>
|
|
||||||
typename Visitor::ResultType apply_binary_visitor_impl2(Visitor & visitor, F1 & field1, F2 & field2)
|
|
||||||
{
|
|
||||||
switch (field2.getType())
|
|
||||||
{
|
|
||||||
case Field::Types::Null: return visitor(field1, field2.template get<Null>());
|
|
||||||
case Field::Types::UInt64: return visitor(field1, field2.template get<UInt64>());
|
|
||||||
case Field::Types::Int64: return visitor(field1, field2.template get<Int64>());
|
|
||||||
case Field::Types::Float64: return visitor(field1, field2.template get<Float64>());
|
|
||||||
case Field::Types::String: return visitor(field1, field2.template get<String>());
|
|
||||||
case Field::Types::Array: return visitor(field1, field2.template get<Array>());
|
|
||||||
|
|
||||||
default:
|
|
||||||
throw Exception("Bad type of Field", ErrorCodes::BAD_TYPE_OF_FIELD);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename Visitor, typename F1, typename F2>
|
|
||||||
typename Visitor::ResultType apply_binary_visitor_impl1(Visitor & visitor, F1 & field1, F2 & field2)
|
|
||||||
{
|
|
||||||
switch (field1.getType())
|
|
||||||
{
|
|
||||||
case Field::Types::Null: return apply_binary_visitor_impl2(visitor, field1.template get<Null>(), field2);
|
|
||||||
case Field::Types::UInt64: return apply_binary_visitor_impl2(visitor, field1.template get<UInt64>(), field2);
|
|
||||||
case Field::Types::Int64: return apply_binary_visitor_impl2(visitor, field1.template get<Int64>(), field2);
|
|
||||||
case Field::Types::Float64: return apply_binary_visitor_impl2(visitor, field1.template get<Float64>(), field2);
|
|
||||||
case Field::Types::String: return apply_binary_visitor_impl2(visitor, field1.template get<String>(), field2);
|
|
||||||
case Field::Types::Array: return apply_binary_visitor_impl2(visitor, field1.template get<Array>(), field2);
|
|
||||||
|
|
||||||
default:
|
|
||||||
throw Exception("Bad type of Field", ErrorCodes::BAD_TYPE_OF_FIELD);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename Visitor>
|
|
||||||
typename Visitor::ResultType apply_visitor(Visitor & visitor, Field & field1, Field & field2)
|
|
||||||
{
|
|
||||||
return apply_binary_visitor_impl1(visitor, field1, field2);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename Visitor>
|
|
||||||
typename Visitor::ResultType apply_visitor(Visitor & visitor, Field & field1, const Field & field2)
|
|
||||||
{
|
|
||||||
return apply_binary_visitor_impl1(visitor, field1, field2);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename Visitor>
|
|
||||||
typename Visitor::ResultType apply_visitor(Visitor & visitor, const Field & field1, Field & field2)
|
|
||||||
{
|
|
||||||
return apply_binary_visitor_impl1(visitor, field1, field2);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename Visitor>
|
|
||||||
typename Visitor::ResultType apply_visitor(Visitor & visitor, const Field & field1, const Field & field2)
|
|
||||||
{
|
|
||||||
return apply_binary_visitor_impl1(visitor, field1, field2);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename Visitor>
|
|
||||||
typename Visitor::ResultType apply_visitor(const Visitor & visitor, Field & field1, Field & field2)
|
|
||||||
{
|
|
||||||
return apply_binary_visitor_impl1(visitor, field1, field2);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename Visitor>
|
|
||||||
typename Visitor::ResultType apply_visitor(const Visitor & visitor, Field & field1, const Field & field2)
|
|
||||||
{
|
|
||||||
return apply_binary_visitor_impl1(visitor, field1, field2);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename Visitor>
|
|
||||||
typename Visitor::ResultType apply_visitor(const Visitor & visitor, const Field & field1, Field & field2)
|
|
||||||
{
|
|
||||||
return apply_binary_visitor_impl1(visitor, field1, field2);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename Visitor>
|
|
||||||
typename Visitor::ResultType apply_visitor(const Visitor & visitor, const Field & field1, const Field & field2)
|
|
||||||
{
|
|
||||||
return apply_binary_visitor_impl1(visitor, field1, field2);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
template <> struct TypeName<Array> { static std::string get() { return "Array"; } };
|
template <> struct TypeName<Array> { static std::string get() { return "Array"; } };
|
||||||
|
|
||||||
|
|
||||||
/** Возвращает строковый дамп типа */
|
|
||||||
class FieldVisitorDump : public StaticVisitor<String>
|
|
||||||
{
|
|
||||||
private:
|
|
||||||
template <typename T>
|
|
||||||
static inline String formatQuotedWithPrefix(T x, const char * prefix)
|
|
||||||
{
|
|
||||||
String res;
|
|
||||||
WriteBufferFromString wb(res);
|
|
||||||
wb.write(prefix, strlen(prefix));
|
|
||||||
writeQuoted(x, wb);
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
public:
|
|
||||||
String operator() (const Null & x) const { return "NULL"; }
|
|
||||||
String operator() (const UInt64 & x) const { return formatQuotedWithPrefix(x, "UInt64_"); }
|
|
||||||
String operator() (const Int64 & x) const { return formatQuotedWithPrefix(x, "Int64_"); }
|
|
||||||
String operator() (const Float64 & x) const { return formatQuotedWithPrefix(x, "Float64_"); }
|
|
||||||
|
|
||||||
String operator() (const String & x) const
|
|
||||||
{
|
|
||||||
String res;
|
|
||||||
WriteBufferFromString wb(res);
|
|
||||||
writeQuoted(x, wb);
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
|
|
||||||
String operator() (const Array & x) const
|
|
||||||
{
|
|
||||||
String res;
|
|
||||||
WriteBufferFromString wb(res);
|
|
||||||
FieldVisitorDump visitor;
|
|
||||||
|
|
||||||
wb.write("Array_[", 7);
|
|
||||||
for (Array::const_iterator it = x.begin(); it != x.end(); ++it)
|
|
||||||
{
|
|
||||||
if (it != x.begin())
|
|
||||||
wb.write(", ", 2);
|
|
||||||
writeString(apply_visitor(visitor, *it), wb);
|
|
||||||
}
|
|
||||||
writeChar(']', wb);
|
|
||||||
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
/** Выводит текстовое представление типа, как литерала в SQL запросе */
|
|
||||||
class FieldVisitorToString : public StaticVisitor<String>
|
|
||||||
{
|
|
||||||
private:
|
|
||||||
template <typename T>
|
|
||||||
static inline String formatQuoted(T x)
|
|
||||||
{
|
|
||||||
String res;
|
|
||||||
WriteBufferFromString wb(res);
|
|
||||||
writeQuoted(x, wb);
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** В отличие от writeFloatText (и writeQuoted), если число после форматирования выглядит целым, всё равно добавляет десятичную точку.
|
|
||||||
* - для того, чтобы это число могло обратно распарситься как Float64 парсером запроса (иначе распарсится как целое).
|
|
||||||
*
|
|
||||||
* При этом, не оставляет завершающие нули справа.
|
|
||||||
*
|
|
||||||
* NOTE: При таком roundtrip-е, точность может теряться.
|
|
||||||
*/
|
|
||||||
static String formatFloat(const Float64 x)
|
|
||||||
{
|
|
||||||
char tmp[25];
|
|
||||||
double_conversion::StringBuilder builder{tmp, sizeof(tmp)};
|
|
||||||
|
|
||||||
const auto result = getDoubleToStringConverter().ToShortest(x, &builder);
|
|
||||||
|
|
||||||
if (!result)
|
|
||||||
throw Exception("Cannot print float or double number", ErrorCodes::CANNOT_PRINT_FLOAT_OR_DOUBLE_NUMBER);
|
|
||||||
|
|
||||||
return { tmp, tmp + builder.position() };
|
|
||||||
}
|
|
||||||
|
|
||||||
public:
|
|
||||||
String operator() (const Null & x) const { return "NULL"; }
|
|
||||||
String operator() (const UInt64 & x) const { return formatQuoted(x); }
|
|
||||||
String operator() (const Int64 & x) const { return formatQuoted(x); }
|
|
||||||
String operator() (const Float64 & x) const { return formatFloat(x); }
|
|
||||||
String operator() (const String & x) const { return formatQuoted(x); }
|
|
||||||
|
|
||||||
String operator() (const Array & x) const
|
|
||||||
{
|
|
||||||
String res;
|
|
||||||
WriteBufferFromString wb(res);
|
|
||||||
FieldVisitorToString visitor;
|
|
||||||
|
|
||||||
writeChar('[', wb);
|
|
||||||
for (Array::const_iterator it = x.begin(); it != x.end(); ++it)
|
|
||||||
{
|
|
||||||
if (it != x.begin())
|
|
||||||
wb.write(", ", 2);
|
|
||||||
writeString(apply_visitor(visitor, *it), wb);
|
|
||||||
}
|
|
||||||
writeChar(']', wb);
|
|
||||||
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
/** Числовой тип преобразует в указанный. */
|
|
||||||
template <typename T>
|
|
||||||
class FieldVisitorConvertToNumber : public StaticVisitor<T>
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
T operator() (const Null & x) const
|
|
||||||
{
|
|
||||||
throw Exception("Cannot convert NULL to " + TypeName<T>::get(), ErrorCodes::CANNOT_CONVERT_TYPE);
|
|
||||||
}
|
|
||||||
|
|
||||||
T operator() (const String & x) const
|
|
||||||
{
|
|
||||||
throw Exception("Cannot convert String to " + TypeName<T>::get(), ErrorCodes::CANNOT_CONVERT_TYPE);
|
|
||||||
}
|
|
||||||
|
|
||||||
T operator() (const Array & x) const
|
|
||||||
{
|
|
||||||
throw Exception("Cannot convert Array to " + TypeName<T>::get(), ErrorCodes::CANNOT_CONVERT_TYPE);
|
|
||||||
}
|
|
||||||
|
|
||||||
T operator() (const UInt64 & x) const { return x; }
|
|
||||||
T operator() (const Int64 & x) const { return x; }
|
|
||||||
T operator() (const Float64 & x) const { return x; }
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
template <typename T> struct NearestFieldType;
|
template <typename T> struct NearestFieldType;
|
||||||
|
|
||||||
template <> struct NearestFieldType<UInt8> { typedef UInt64 Type; };
|
template <> struct NearestFieldType<UInt8> { typedef UInt64 Type; };
|
||||||
@ -684,27 +406,14 @@ typename NearestFieldType<T>::Type nearestFieldType(const T & x)
|
|||||||
|
|
||||||
|
|
||||||
/// Заглушки, чтобы DBObject-ы с полем типа Array компилировались.
|
/// Заглушки, чтобы DBObject-ы с полем типа Array компилировались.
|
||||||
|
#include <mysqlxx/Manip.h>
|
||||||
|
|
||||||
namespace mysqlxx
|
namespace mysqlxx
|
||||||
{
|
{
|
||||||
inline std::ostream & operator<< (mysqlxx::EscapeManipResult res, const DB::Array & value)
|
std::ostream & operator<< (mysqlxx::EscapeManipResult res, const DB::Array & value);
|
||||||
{
|
std::ostream & operator<< (mysqlxx::QuoteManipResult res, const DB::Array & value);
|
||||||
return res.ostr << apply_visitor(DB::FieldVisitorToString(), value);
|
std::istream & operator>> (mysqlxx::UnEscapeManipResult res, DB::Array & value);
|
||||||
}
|
std::istream & operator>> (mysqlxx::UnQuoteManipResult res, DB::Array & value);
|
||||||
|
|
||||||
inline std::ostream & operator<< (mysqlxx::QuoteManipResult res, const DB::Array & value)
|
|
||||||
{
|
|
||||||
throw Poco::Exception("Cannot quote Array with mysqlxx::quote.");
|
|
||||||
}
|
|
||||||
|
|
||||||
inline std::istream & operator>> (mysqlxx::UnEscapeManipResult res, DB::Array & value)
|
|
||||||
{
|
|
||||||
throw Poco::Exception("Cannot unescape Array with mysqlxx::unescape.");
|
|
||||||
}
|
|
||||||
|
|
||||||
inline std::istream & operator>> (mysqlxx::UnQuoteManipResult res, DB::Array & value)
|
|
||||||
{
|
|
||||||
throw Poco::Exception("Cannot unquote Array with mysqlxx::unquote.");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -714,116 +423,15 @@ namespace DB
|
|||||||
class WriteBuffer;
|
class WriteBuffer;
|
||||||
|
|
||||||
/// Предполагается что у всех элементов массива одинаковый тип.
|
/// Предполагается что у всех элементов массива одинаковый тип.
|
||||||
inline void readBinary(Array & x, ReadBuffer & buf)
|
void readBinary(Array & x, ReadBuffer & buf);
|
||||||
{
|
|
||||||
size_t size;
|
|
||||||
UInt8 type;
|
|
||||||
DB::readBinary(type, buf);
|
|
||||||
DB::readBinary(size, buf);
|
|
||||||
|
|
||||||
for (size_t index = 0; index < size; ++index)
|
|
||||||
{
|
|
||||||
switch (type)
|
|
||||||
{
|
|
||||||
case Field::Types::Null:
|
|
||||||
{
|
|
||||||
x.push_back(DB::Field());
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case Field::Types::UInt64:
|
|
||||||
{
|
|
||||||
UInt64 value;
|
|
||||||
DB::readVarUInt(value, buf);
|
|
||||||
x.push_back(value);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case Field::Types::Int64:
|
|
||||||
{
|
|
||||||
Int64 value;
|
|
||||||
DB::readVarInt(value, buf);
|
|
||||||
x.push_back(value);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case Field::Types::Float64:
|
|
||||||
{
|
|
||||||
Float64 value;
|
|
||||||
DB::readFloatBinary(value, buf);
|
|
||||||
x.push_back(value);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case Field::Types::String:
|
|
||||||
{
|
|
||||||
std::string value;
|
|
||||||
DB::readStringBinary(value, buf);
|
|
||||||
x.push_back(value);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case Field::Types::Array:
|
|
||||||
{
|
|
||||||
Array value;
|
|
||||||
DB::readBinary(value, buf);
|
|
||||||
x.push_back(value);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
inline void readText(Array & x, ReadBuffer & buf) { throw Exception("Cannot read Array.", ErrorCodes::NOT_IMPLEMENTED); }
|
inline void readText(Array & x, ReadBuffer & buf) { throw Exception("Cannot read Array.", ErrorCodes::NOT_IMPLEMENTED); }
|
||||||
inline void readQuoted(Array & x, ReadBuffer & buf) { throw Exception("Cannot read Array.", ErrorCodes::NOT_IMPLEMENTED); }
|
inline void readQuoted(Array & x, ReadBuffer & buf) { throw Exception("Cannot read Array.", ErrorCodes::NOT_IMPLEMENTED); }
|
||||||
|
|
||||||
/// Предполагается что у всех элементов массива одинаковый тип.
|
/// Предполагается что у всех элементов массива одинаковый тип.
|
||||||
inline void writeBinary(const Array & x, WriteBuffer & buf)
|
void writeBinary(const Array & x, WriteBuffer & buf);
|
||||||
{
|
|
||||||
UInt8 type = Field::Types::Null;
|
|
||||||
size_t size = x.size();
|
|
||||||
if (size)
|
|
||||||
type = x.front().getType();
|
|
||||||
DB::writeBinary(type, buf);
|
|
||||||
DB::writeBinary(size, buf);
|
|
||||||
|
|
||||||
for (Array::const_iterator it = x.begin(); it != x.end(); ++it)
|
void writeText(const Array & x, WriteBuffer & buf);
|
||||||
{
|
|
||||||
switch (type)
|
|
||||||
{
|
|
||||||
case Field::Types::Null: break;
|
|
||||||
case Field::Types::UInt64:
|
|
||||||
{
|
|
||||||
DB::writeVarUInt(get<UInt64>(*it), buf);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case Field::Types::Int64:
|
|
||||||
{
|
|
||||||
DB::writeVarInt(get<Int64>(*it), buf);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case Field::Types::Float64:
|
|
||||||
{
|
|
||||||
DB::writeFloatBinary(get<Float64>(*it), buf);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case Field::Types::String:
|
|
||||||
{
|
|
||||||
DB::writeStringBinary(get<std::string>(*it), buf);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case Field::Types::Array:
|
|
||||||
{
|
|
||||||
DB::writeBinary(get<Array>(*it), buf);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
inline void writeText(const Array & x, WriteBuffer & buf)
|
|
||||||
{
|
|
||||||
DB::String res = apply_visitor(DB::FieldVisitorToString(), DB::Field(x));
|
|
||||||
buf.write(res.data(), res.size());
|
|
||||||
}
|
|
||||||
|
|
||||||
inline void writeQuoted(const Array & x, WriteBuffer & buf) { throw Exception("Cannot write Array quoted.", ErrorCodes::NOT_IMPLEMENTED); }
|
inline void writeQuoted(const Array & x, WriteBuffer & buf) { throw Exception("Cannot write Array quoted.", ErrorCodes::NOT_IMPLEMENTED); }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#undef DBMS_TOTAL_FIELD_SIZE
|
|
||||||
|
344
dbms/include/DB/Core/FieldVisitors.h
Normal file
344
dbms/include/DB/Core/FieldVisitors.h
Normal file
@ -0,0 +1,344 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <DB/Core/Field.h>
|
||||||
|
|
||||||
|
#include <DB/IO/ReadBuffer.h>
|
||||||
|
#include <DB/IO/WriteBuffer.h>
|
||||||
|
#include <DB/IO/ReadHelpers.h>
|
||||||
|
#include <DB/IO/WriteHelpers.h>
|
||||||
|
#include <DB/IO/ReadBufferFromString.h>
|
||||||
|
#include <DB/IO/WriteBufferFromString.h>
|
||||||
|
|
||||||
|
|
||||||
|
namespace DB
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
/** StaticVisitor (его наследники) - класс с перегруженными для разных типов операторами ().
|
||||||
|
* Вызвать visitor для field можно с помощью функции apply_visitor.
|
||||||
|
* Также поддерживается visitor, в котором оператор () принимает два аргумента.
|
||||||
|
*/
|
||||||
|
template <typename R = void>
|
||||||
|
struct StaticVisitor
|
||||||
|
{
|
||||||
|
typedef R ResultType;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
template <typename Visitor, typename F>
|
||||||
|
typename Visitor::ResultType apply_visitor_impl(Visitor & visitor, F & field)
|
||||||
|
{
|
||||||
|
switch (field.getType())
|
||||||
|
{
|
||||||
|
case Field::Types::Null: return visitor(field.template get<Null>());
|
||||||
|
case Field::Types::UInt64: return visitor(field.template get<UInt64>());
|
||||||
|
case Field::Types::Int64: return visitor(field.template get<Int64>());
|
||||||
|
case Field::Types::Float64: return visitor(field.template get<Float64>());
|
||||||
|
case Field::Types::String: return visitor(field.template get<String>());
|
||||||
|
case Field::Types::Array: return visitor(field.template get<Array>());
|
||||||
|
|
||||||
|
default:
|
||||||
|
throw Exception("Bad type of Field", ErrorCodes::BAD_TYPE_OF_FIELD);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Эти штуки нужны, чтобы принимать временный объект по константной ссылке.
|
||||||
|
* В шаблон выше, типы форвардятся уже с const-ом.
|
||||||
|
*/
|
||||||
|
|
||||||
|
template <typename Visitor>
|
||||||
|
typename Visitor::ResultType apply_visitor(const Visitor & visitor, Field & field)
|
||||||
|
{
|
||||||
|
return apply_visitor_impl(visitor, field);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename Visitor>
|
||||||
|
typename Visitor::ResultType apply_visitor(const Visitor & visitor, const Field & field)
|
||||||
|
{
|
||||||
|
return apply_visitor_impl(visitor, field);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename Visitor>
|
||||||
|
typename Visitor::ResultType apply_visitor(Visitor & visitor, Field & field)
|
||||||
|
{
|
||||||
|
return apply_visitor_impl(visitor, field);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename Visitor>
|
||||||
|
typename Visitor::ResultType apply_visitor(Visitor & visitor, const Field & field)
|
||||||
|
{
|
||||||
|
return apply_visitor_impl(visitor, field);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template <typename Visitor, typename F1, typename F2>
|
||||||
|
typename Visitor::ResultType apply_binary_visitor_impl2(Visitor & visitor, F1 & field1, F2 & field2)
|
||||||
|
{
|
||||||
|
switch (field2.getType())
|
||||||
|
{
|
||||||
|
case Field::Types::Null: return visitor(field1, field2.template get<Null>());
|
||||||
|
case Field::Types::UInt64: return visitor(field1, field2.template get<UInt64>());
|
||||||
|
case Field::Types::Int64: return visitor(field1, field2.template get<Int64>());
|
||||||
|
case Field::Types::Float64: return visitor(field1, field2.template get<Float64>());
|
||||||
|
case Field::Types::String: return visitor(field1, field2.template get<String>());
|
||||||
|
case Field::Types::Array: return visitor(field1, field2.template get<Array>());
|
||||||
|
|
||||||
|
default:
|
||||||
|
throw Exception("Bad type of Field", ErrorCodes::BAD_TYPE_OF_FIELD);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename Visitor, typename F1, typename F2>
|
||||||
|
typename Visitor::ResultType apply_binary_visitor_impl1(Visitor & visitor, F1 & field1, F2 & field2)
|
||||||
|
{
|
||||||
|
switch (field1.getType())
|
||||||
|
{
|
||||||
|
case Field::Types::Null: return apply_binary_visitor_impl2(visitor, field1.template get<Null>(), field2);
|
||||||
|
case Field::Types::UInt64: return apply_binary_visitor_impl2(visitor, field1.template get<UInt64>(), field2);
|
||||||
|
case Field::Types::Int64: return apply_binary_visitor_impl2(visitor, field1.template get<Int64>(), field2);
|
||||||
|
case Field::Types::Float64: return apply_binary_visitor_impl2(visitor, field1.template get<Float64>(), field2);
|
||||||
|
case Field::Types::String: return apply_binary_visitor_impl2(visitor, field1.template get<String>(), field2);
|
||||||
|
case Field::Types::Array: return apply_binary_visitor_impl2(visitor, field1.template get<Array>(), field2);
|
||||||
|
|
||||||
|
default:
|
||||||
|
throw Exception("Bad type of Field", ErrorCodes::BAD_TYPE_OF_FIELD);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename Visitor>
|
||||||
|
typename Visitor::ResultType apply_visitor(Visitor & visitor, Field & field1, Field & field2)
|
||||||
|
{
|
||||||
|
return apply_binary_visitor_impl1(visitor, field1, field2);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename Visitor>
|
||||||
|
typename Visitor::ResultType apply_visitor(Visitor & visitor, Field & field1, const Field & field2)
|
||||||
|
{
|
||||||
|
return apply_binary_visitor_impl1(visitor, field1, field2);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename Visitor>
|
||||||
|
typename Visitor::ResultType apply_visitor(Visitor & visitor, const Field & field1, Field & field2)
|
||||||
|
{
|
||||||
|
return apply_binary_visitor_impl1(visitor, field1, field2);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename Visitor>
|
||||||
|
typename Visitor::ResultType apply_visitor(Visitor & visitor, const Field & field1, const Field & field2)
|
||||||
|
{
|
||||||
|
return apply_binary_visitor_impl1(visitor, field1, field2);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename Visitor>
|
||||||
|
typename Visitor::ResultType apply_visitor(const Visitor & visitor, Field & field1, Field & field2)
|
||||||
|
{
|
||||||
|
return apply_binary_visitor_impl1(visitor, field1, field2);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename Visitor>
|
||||||
|
typename Visitor::ResultType apply_visitor(const Visitor & visitor, Field & field1, const Field & field2)
|
||||||
|
{
|
||||||
|
return apply_binary_visitor_impl1(visitor, field1, field2);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename Visitor>
|
||||||
|
typename Visitor::ResultType apply_visitor(const Visitor & visitor, const Field & field1, Field & field2)
|
||||||
|
{
|
||||||
|
return apply_binary_visitor_impl1(visitor, field1, field2);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename Visitor>
|
||||||
|
typename Visitor::ResultType apply_visitor(const Visitor & visitor, const Field & field1, const Field & field2)
|
||||||
|
{
|
||||||
|
return apply_binary_visitor_impl1(visitor, field1, field2);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/** Возвращает строковый дамп типа */
|
||||||
|
class FieldVisitorDump : public StaticVisitor<String>
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
template <typename T>
|
||||||
|
static inline String formatQuotedWithPrefix(T x, const char * prefix)
|
||||||
|
{
|
||||||
|
String res;
|
||||||
|
WriteBufferFromString wb(res);
|
||||||
|
wb.write(prefix, strlen(prefix));
|
||||||
|
writeQuoted(x, wb);
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
public:
|
||||||
|
String operator() (const Null & x) const { return "NULL"; }
|
||||||
|
String operator() (const UInt64 & x) const { return formatQuotedWithPrefix(x, "UInt64_"); }
|
||||||
|
String operator() (const Int64 & x) const { return formatQuotedWithPrefix(x, "Int64_"); }
|
||||||
|
String operator() (const Float64 & x) const { return formatQuotedWithPrefix(x, "Float64_"); }
|
||||||
|
String operator() (const String & x) const;
|
||||||
|
String operator() (const Array & x) const;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/** Выводит текстовое представление типа, как литерала в SQL запросе */
|
||||||
|
class FieldVisitorToString : public StaticVisitor<String>
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
template <typename T>
|
||||||
|
static inline String formatQuoted(T x)
|
||||||
|
{
|
||||||
|
String res;
|
||||||
|
WriteBufferFromString wb(res);
|
||||||
|
writeQuoted(x, wb);
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** В отличие от writeFloatText (и writeQuoted), если число после форматирования выглядит целым, всё равно добавляет десятичную точку.
|
||||||
|
* - для того, чтобы это число могло обратно распарситься как Float64 парсером запроса (иначе распарсится как целое).
|
||||||
|
*
|
||||||
|
* При этом, не оставляет завершающие нули справа.
|
||||||
|
*
|
||||||
|
* NOTE: При таком roundtrip-е, точность может теряться.
|
||||||
|
*/
|
||||||
|
static String formatFloat(const Float64 x);
|
||||||
|
|
||||||
|
public:
|
||||||
|
String operator() (const Null & x) const { return "NULL"; }
|
||||||
|
String operator() (const UInt64 & x) const { return formatQuoted(x); }
|
||||||
|
String operator() (const Int64 & x) const { return formatQuoted(x); }
|
||||||
|
String operator() (const Float64 & x) const { return formatFloat(x); }
|
||||||
|
String operator() (const String & x) const { return formatQuoted(x); }
|
||||||
|
String operator() (const Array & x) const;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/** Числовой тип преобразует в указанный. */
|
||||||
|
template <typename T>
|
||||||
|
class FieldVisitorConvertToNumber : public StaticVisitor<T>
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
T operator() (const Null & x) const
|
||||||
|
{
|
||||||
|
throw Exception("Cannot convert NULL to " + TypeName<T>::get(), ErrorCodes::CANNOT_CONVERT_TYPE);
|
||||||
|
}
|
||||||
|
|
||||||
|
T operator() (const String & x) const
|
||||||
|
{
|
||||||
|
throw Exception("Cannot convert String to " + TypeName<T>::get(), ErrorCodes::CANNOT_CONVERT_TYPE);
|
||||||
|
}
|
||||||
|
|
||||||
|
T operator() (const Array & x) const
|
||||||
|
{
|
||||||
|
throw Exception("Cannot convert Array to " + TypeName<T>::get(), ErrorCodes::CANNOT_CONVERT_TYPE);
|
||||||
|
}
|
||||||
|
|
||||||
|
T operator() (const UInt64 & x) const { return x; }
|
||||||
|
T operator() (const Int64 & x) const { return x; }
|
||||||
|
T operator() (const Float64 & x) const { return x; }
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/// Преобразование строки с датой или датой-с-временем в UInt64, содержащим числовое значение даты или даты-с-временем.
|
||||||
|
UInt64 stringToDateOrDateTime(const String & s);
|
||||||
|
|
||||||
|
|
||||||
|
#pragma GCC diagnostic push
|
||||||
|
#pragma GCC diagnostic ignored "-Wsign-compare"
|
||||||
|
|
||||||
|
/** Более точное сравнение.
|
||||||
|
* Отличается от Field::operator< и Field::operator== тем, что сравнивает значения разных числовых типов между собой.
|
||||||
|
* Правила сравнения - такие же, что и в FunctionsComparison.
|
||||||
|
* В том числе, сравнение знаковых и беззнаковых оставляем UB.
|
||||||
|
*/
|
||||||
|
class FieldVisitorAccurateEquals : public StaticVisitor<bool>
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
bool operator() (const Null & l, const Null & r) const { return true; }
|
||||||
|
bool operator() (const Null & l, const UInt64 & r) const { return false; }
|
||||||
|
bool operator() (const Null & l, const Int64 & r) const { return false; }
|
||||||
|
bool operator() (const Null & l, const Float64 & r) const { return false; }
|
||||||
|
bool operator() (const Null & l, const String & r) const { return false; }
|
||||||
|
bool operator() (const Null & l, const Array & r) const { return false; }
|
||||||
|
|
||||||
|
bool operator() (const UInt64 & l, const Null & r) const { return false; }
|
||||||
|
bool operator() (const UInt64 & l, const UInt64 & r) const { return l == r; }
|
||||||
|
bool operator() (const UInt64 & l, const Int64 & r) const { return l == r; }
|
||||||
|
bool operator() (const UInt64 & l, const Float64 & r) const { return l == r; }
|
||||||
|
bool operator() (const UInt64 & l, const String & r) const { return l == stringToDateOrDateTime(r); }
|
||||||
|
bool operator() (const UInt64 & l, const Array & r) const { return false; }
|
||||||
|
|
||||||
|
bool operator() (const Int64 & l, const Null & r) const { return false; }
|
||||||
|
bool operator() (const Int64 & l, const UInt64 & r) const { return l == r; }
|
||||||
|
bool operator() (const Int64 & l, const Int64 & r) const { return l == r; }
|
||||||
|
bool operator() (const Int64 & l, const Float64 & r) const { return l == r; }
|
||||||
|
bool operator() (const Int64 & l, const String & r) const { return false; }
|
||||||
|
bool operator() (const Int64 & l, const Array & r) const { return false; }
|
||||||
|
|
||||||
|
bool operator() (const Float64 & l, const Null & r) const { return false; }
|
||||||
|
bool operator() (const Float64 & l, const UInt64 & r) const { return l == r; }
|
||||||
|
bool operator() (const Float64 & l, const Int64 & r) const { return l == r; }
|
||||||
|
bool operator() (const Float64 & l, const Float64 & r) const { return l == r; }
|
||||||
|
bool operator() (const Float64 & l, const String & r) const { return false; }
|
||||||
|
bool operator() (const Float64 & l, const Array & r) const { return false; }
|
||||||
|
|
||||||
|
bool operator() (const String & l, const Null & r) const { return false; }
|
||||||
|
bool operator() (const String & l, const UInt64 & r) const { return stringToDateOrDateTime(l) == r; }
|
||||||
|
bool operator() (const String & l, const Int64 & r) const { return false; }
|
||||||
|
bool operator() (const String & l, const Float64 & r) const { return false; }
|
||||||
|
bool operator() (const String & l, const String & r) const { return l == r; }
|
||||||
|
bool operator() (const String & l, const Array & r) const { return false; }
|
||||||
|
|
||||||
|
bool operator() (const Array & l, const Null & r) const { return false; }
|
||||||
|
bool operator() (const Array & l, const UInt64 & r) const { return false; }
|
||||||
|
bool operator() (const Array & l, const Int64 & r) const { return false; }
|
||||||
|
bool operator() (const Array & l, const Float64 & r) const { return false; }
|
||||||
|
bool operator() (const Array & l, const String & r) const { return false; }
|
||||||
|
bool operator() (const Array & l, const Array & r) const { return l == r; }
|
||||||
|
};
|
||||||
|
|
||||||
|
class FieldVisitorAccurateLess : public StaticVisitor<bool>
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
bool operator() (const Null & l, const Null & r) const { return false; }
|
||||||
|
bool operator() (const Null & l, const UInt64 & r) const { return true; }
|
||||||
|
bool operator() (const Null & l, const Int64 & r) const { return true; }
|
||||||
|
bool operator() (const Null & l, const Float64 & r) const { return true; }
|
||||||
|
bool operator() (const Null & l, const String & r) const { return true; }
|
||||||
|
bool operator() (const Null & l, const Array & r) const { return true; }
|
||||||
|
|
||||||
|
bool operator() (const UInt64 & l, const Null & r) const { return false; }
|
||||||
|
bool operator() (const UInt64 & l, const UInt64 & r) const { return l < r; }
|
||||||
|
bool operator() (const UInt64 & l, const Int64 & r) const { return l < r; }
|
||||||
|
bool operator() (const UInt64 & l, const Float64 & r) const { return l < r; }
|
||||||
|
bool operator() (const UInt64 & l, const String & r) const { return l < stringToDateOrDateTime(r); }
|
||||||
|
bool operator() (const UInt64 & l, const Array & r) const { return true; }
|
||||||
|
|
||||||
|
bool operator() (const Int64 & l, const Null & r) const { return false; }
|
||||||
|
bool operator() (const Int64 & l, const UInt64 & r) const { return l < r; }
|
||||||
|
bool operator() (const Int64 & l, const Int64 & r) const { return l < r; }
|
||||||
|
bool operator() (const Int64 & l, const Float64 & r) const { return l < r; }
|
||||||
|
bool operator() (const Int64 & l, const String & r) const { return true; }
|
||||||
|
bool operator() (const Int64 & l, const Array & r) const { return true; }
|
||||||
|
|
||||||
|
bool operator() (const Float64 & l, const Null & r) const { return false; }
|
||||||
|
bool operator() (const Float64 & l, const UInt64 & r) const { return l < r; }
|
||||||
|
bool operator() (const Float64 & l, const Int64 & r) const { return l < r; }
|
||||||
|
bool operator() (const Float64 & l, const Float64 & r) const { return l < r; }
|
||||||
|
bool operator() (const Float64 & l, const String & r) const { return true; }
|
||||||
|
bool operator() (const Float64 & l, const Array & r) const { return true; }
|
||||||
|
|
||||||
|
bool operator() (const String & l, const Null & r) const { return false; }
|
||||||
|
bool operator() (const String & l, const UInt64 & r) const { return stringToDateOrDateTime(l) < r; }
|
||||||
|
bool operator() (const String & l, const Int64 & r) const { return false; }
|
||||||
|
bool operator() (const String & l, const Float64 & r) const { return false; }
|
||||||
|
bool operator() (const String & l, const String & r) const { return l < r; }
|
||||||
|
bool operator() (const String & l, const Array & r) const { return true; }
|
||||||
|
|
||||||
|
bool operator() (const Array & l, const Null & r) const { return false; }
|
||||||
|
bool operator() (const Array & l, const UInt64 & r) const { return false; }
|
||||||
|
bool operator() (const Array & l, const Int64 & r) const { return false; }
|
||||||
|
bool operator() (const Array & l, const Float64 & r) const { return false; }
|
||||||
|
bool operator() (const Array & l, const String & r) const { return false; }
|
||||||
|
bool operator() (const Array & l, const Array & r) const { return l < r; }
|
||||||
|
};
|
||||||
|
|
||||||
|
#pragma GCC diagnostic pop
|
||||||
|
|
||||||
|
}
|
@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
#include <common/logger_useful.h>
|
#include <common/logger_useful.h>
|
||||||
|
|
||||||
|
#include <DB/Core/FieldVisitors.h>
|
||||||
#include <DB/Core/Row.h>
|
#include <DB/Core/Row.h>
|
||||||
#include <DB/Core/ColumnNumbers.h>
|
#include <DB/Core/ColumnNumbers.h>
|
||||||
#include <DB/DataStreams/MergingSortedBlockInputStream.h>
|
#include <DB/DataStreams/MergingSortedBlockInputStream.h>
|
||||||
|
@ -28,29 +28,7 @@ public:
|
|||||||
|
|
||||||
std::string getFunctionName() const { return function->getName(); }
|
std::string getFunctionName() const { return function->getName(); }
|
||||||
|
|
||||||
std::string getName() const override
|
std::string getName() const override;
|
||||||
{
|
|
||||||
std::stringstream stream;
|
|
||||||
stream << "AggregateFunction(" << function->getName();
|
|
||||||
|
|
||||||
if (!parameters.empty())
|
|
||||||
{
|
|
||||||
stream << "(";
|
|
||||||
for (size_t i = 0; i < parameters.size(); ++i)
|
|
||||||
{
|
|
||||||
if (i)
|
|
||||||
stream << ", ";
|
|
||||||
stream << apply_visitor(DB::FieldVisitorToString(), parameters[i]);
|
|
||||||
}
|
|
||||||
stream << ")";
|
|
||||||
}
|
|
||||||
|
|
||||||
for (DataTypes::const_iterator it = argument_types.begin(); it != argument_types.end(); ++it)
|
|
||||||
stream << ", " << (*it)->getName();
|
|
||||||
|
|
||||||
stream << ")";
|
|
||||||
return stream.str();
|
|
||||||
}
|
|
||||||
|
|
||||||
DataTypePtr getReturnType() const { return function->getReturnType(); };
|
DataTypePtr getReturnType() const { return function->getReturnType(); };
|
||||||
DataTypes getArgumentsDataTypes() const { return argument_types; }
|
DataTypes getArgumentsDataTypes() const { return argument_types; }
|
||||||
|
@ -25,10 +25,7 @@ public:
|
|||||||
throw Exception("FixedString size must be positive", ErrorCodes::ARGUMENT_OUT_OF_BOUND);
|
throw Exception("FixedString size must be positive", ErrorCodes::ARGUMENT_OUT_OF_BOUND);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string getName() const override
|
std::string getName() const override;
|
||||||
{
|
|
||||||
return "FixedString(" + toString(n) + ")";
|
|
||||||
}
|
|
||||||
|
|
||||||
DataTypePtr clone() const override
|
DataTypePtr clone() const override
|
||||||
{
|
{
|
||||||
|
@ -1,5 +1,7 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include <DB/Core/FieldVisitors.h>
|
||||||
|
|
||||||
#include <DB/DataTypes/DataTypesNumberFixed.h>
|
#include <DB/DataTypes/DataTypesNumberFixed.h>
|
||||||
#include <DB/DataTypes/DataTypeString.h>
|
#include <DB/DataTypes/DataTypeString.h>
|
||||||
#include <DB/DataTypes/DataTypeArray.h>
|
#include <DB/DataTypes/DataTypeArray.h>
|
||||||
|
@ -1,7 +1,5 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <boost/function.hpp>
|
|
||||||
|
|
||||||
#include <Poco/SharedPtr.h>
|
#include <Poco/SharedPtr.h>
|
||||||
|
|
||||||
#include <DB/Core/Field.h>
|
#include <DB/Core/Field.h>
|
||||||
|
@ -25,7 +25,7 @@ public:
|
|||||||
ClickHouseDictionarySource(const DictionaryStructure & dict_struct,
|
ClickHouseDictionarySource(const DictionaryStructure & dict_struct,
|
||||||
const Poco::Util::AbstractConfiguration & config,
|
const Poco::Util::AbstractConfiguration & config,
|
||||||
const std::string & config_prefix,
|
const std::string & config_prefix,
|
||||||
Block & sample_block, Context & context)
|
const Block & sample_block, Context & context)
|
||||||
: dict_struct{dict_struct},
|
: dict_struct{dict_struct},
|
||||||
host{config.getString(config_prefix + ".host")},
|
host{config.getString(config_prefix + ".host")},
|
||||||
port(config.getInt(config_prefix + ".port")),
|
port(config.getInt(config_prefix + ".port")),
|
||||||
|
@ -5,6 +5,7 @@
|
|||||||
#include <DB/Dictionaries/FileDictionarySource.h>
|
#include <DB/Dictionaries/FileDictionarySource.h>
|
||||||
#include <DB/Dictionaries/MySQLDictionarySource.h>
|
#include <DB/Dictionaries/MySQLDictionarySource.h>
|
||||||
#include <DB/Dictionaries/ClickHouseDictionarySource.h>
|
#include <DB/Dictionaries/ClickHouseDictionarySource.h>
|
||||||
|
//#include <DB/Dictionaries/MongoDBDictionarySource.h>
|
||||||
#include <DB/DataTypes/DataTypesNumberFixed.h>
|
#include <DB/DataTypes/DataTypesNumberFixed.h>
|
||||||
#include <common/singleton.h>
|
#include <common/singleton.h>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
@ -84,6 +85,11 @@ public:
|
|||||||
return std::make_unique<ClickHouseDictionarySource>(dict_struct, config, config_prefix + ".clickhouse",
|
return std::make_unique<ClickHouseDictionarySource>(dict_struct, config, config_prefix + ".clickhouse",
|
||||||
sample_block, context);
|
sample_block, context);
|
||||||
}
|
}
|
||||||
|
/* else if ("mongodb" == source_type)
|
||||||
|
{
|
||||||
|
return std::make_unique<MongoDBDictionarySource>(dict_struct, config, config_prefix + ".mongodb",
|
||||||
|
sample_block, context);
|
||||||
|
}*/
|
||||||
|
|
||||||
throw Exception{
|
throw Exception{
|
||||||
name + ": unknown dictionary source type: " + source_type,
|
name + ": unknown dictionary source type: " + source_type,
|
||||||
|
@ -3,6 +3,8 @@
|
|||||||
#include <DB/Core/ErrorCodes.h>
|
#include <DB/Core/ErrorCodes.h>
|
||||||
#include <DB/DataTypes/DataTypeFactory.h>
|
#include <DB/DataTypes/DataTypeFactory.h>
|
||||||
#include <DB/IO/ReadBufferFromString.h>
|
#include <DB/IO/ReadBufferFromString.h>
|
||||||
|
#include <DB/IO/WriteBuffer.h>
|
||||||
|
#include <DB/IO/WriteHelpers.h>
|
||||||
#include <Poco/Util/AbstractConfiguration.h>
|
#include <Poco/Util/AbstractConfiguration.h>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
315
dbms/include/DB/Dictionaries/MongoDBBlockInputStream.h
Normal file
315
dbms/include/DB/Dictionaries/MongoDBBlockInputStream.h
Normal file
@ -0,0 +1,315 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <DB/Core/Block.h>
|
||||||
|
#include <DB/DataStreams/IProfilingBlockInputStream.h>
|
||||||
|
#include <DB/DataTypes/DataTypesNumberFixed.h>
|
||||||
|
#include <DB/DataTypes/DataTypeString.h>
|
||||||
|
#include <DB/DataTypes/DataTypeDate.h>
|
||||||
|
#include <DB/DataTypes/DataTypeDateTime.h>
|
||||||
|
#include <DB/Columns/ColumnString.h>
|
||||||
|
#include <ext/range.hpp>
|
||||||
|
#include <mongo/client/dbclient.h>
|
||||||
|
#include <vector>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
namespace DB
|
||||||
|
{
|
||||||
|
|
||||||
|
/// Allows processing results of a MongoDB query as a sequence of Blocks, simplifies chaining
|
||||||
|
class MongoDBBlockInputStream final : public IProfilingBlockInputStream
|
||||||
|
{
|
||||||
|
enum struct value_type_t
|
||||||
|
{
|
||||||
|
UInt8,
|
||||||
|
UInt16,
|
||||||
|
UInt32,
|
||||||
|
UInt64,
|
||||||
|
Int8,
|
||||||
|
Int16,
|
||||||
|
Int32,
|
||||||
|
Int64,
|
||||||
|
Float32,
|
||||||
|
Float64,
|
||||||
|
String,
|
||||||
|
Date,
|
||||||
|
DateTime
|
||||||
|
};
|
||||||
|
|
||||||
|
public:
|
||||||
|
MongoDBBlockInputStream(
|
||||||
|
std::unique_ptr<mongo::DBClientCursor> cursor_, const Block & sample_block, const std::size_t max_block_size)
|
||||||
|
: cursor{std::move(cursor_)}, sample_block{sample_block}, max_block_size{max_block_size}
|
||||||
|
{
|
||||||
|
if (!cursor->more())
|
||||||
|
return;
|
||||||
|
|
||||||
|
types.reserve(sample_block.columns());
|
||||||
|
|
||||||
|
for (const auto idx : ext::range(0, sample_block.columns()))
|
||||||
|
{
|
||||||
|
const auto & column = sample_block.getByPosition(idx);
|
||||||
|
const auto type = column.type.get();
|
||||||
|
|
||||||
|
if (typeid_cast<const DataTypeUInt8 *>(type))
|
||||||
|
types.push_back(value_type_t::UInt8);
|
||||||
|
else if (typeid_cast<const DataTypeUInt16 *>(type))
|
||||||
|
types.push_back(value_type_t::UInt16);
|
||||||
|
else if (typeid_cast<const DataTypeUInt32 *>(type))
|
||||||
|
types.push_back(value_type_t::UInt32);
|
||||||
|
else if (typeid_cast<const DataTypeUInt64 *>(type))
|
||||||
|
types.push_back(value_type_t::UInt64);
|
||||||
|
else if (typeid_cast<const DataTypeInt8 *>(type))
|
||||||
|
types.push_back(value_type_t::Int8);
|
||||||
|
else if (typeid_cast<const DataTypeInt16 *>(type))
|
||||||
|
types.push_back(value_type_t::Int16);
|
||||||
|
else if (typeid_cast<const DataTypeInt32 *>(type))
|
||||||
|
types.push_back(value_type_t::Int32);
|
||||||
|
else if (typeid_cast<const DataTypeInt64 *>(type))
|
||||||
|
types.push_back(value_type_t::Int64);
|
||||||
|
else if (typeid_cast<const DataTypeFloat32 *>(type))
|
||||||
|
types.push_back(value_type_t::Float32);
|
||||||
|
else if (typeid_cast<const DataTypeInt64 *>(type))
|
||||||
|
types.push_back(value_type_t::Float64);
|
||||||
|
else if (typeid_cast<const DataTypeString *>(type))
|
||||||
|
types.push_back(value_type_t::String);
|
||||||
|
else if (typeid_cast<const DataTypeDate *>(type))
|
||||||
|
types.push_back(value_type_t::Date);
|
||||||
|
else if (typeid_cast<const DataTypeDateTime *>(type))
|
||||||
|
types.push_back(value_type_t::DateTime);
|
||||||
|
else
|
||||||
|
throw Exception{
|
||||||
|
"Unsupported type " + type->getName(),
|
||||||
|
ErrorCodes::UNKNOWN_TYPE
|
||||||
|
};
|
||||||
|
|
||||||
|
names.emplace_back(column.name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
String getName() const override { return "MongoDB"; }
|
||||||
|
|
||||||
|
String getID() const override
|
||||||
|
{
|
||||||
|
using stream = std::ostringstream;
|
||||||
|
|
||||||
|
return "MongoDB(@" + static_cast<stream &>(stream{} << cursor.get()).str() + ")";
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
Block readImpl() override
|
||||||
|
{
|
||||||
|
if (!cursor->more())
|
||||||
|
return {};
|
||||||
|
|
||||||
|
auto block = sample_block.cloneEmpty();
|
||||||
|
|
||||||
|
/// cache pointers returned by the calls to getByPosition
|
||||||
|
std::vector<IColumn *> columns(block.columns());
|
||||||
|
const auto size = columns.size();
|
||||||
|
|
||||||
|
for (const auto i : ext::range(0, size))
|
||||||
|
columns[i] = block.getByPosition(i).column.get();
|
||||||
|
|
||||||
|
std::size_t num_rows = 0;
|
||||||
|
while (cursor->more())
|
||||||
|
{
|
||||||
|
const auto row = cursor->next();
|
||||||
|
|
||||||
|
for (const auto idx : ext::range(0, size))
|
||||||
|
{
|
||||||
|
const auto value = row[names[idx]];
|
||||||
|
if (value.ok())
|
||||||
|
insertValue(columns[idx], types[idx], value);
|
||||||
|
else
|
||||||
|
insertDefaultValue(columns[idx], types[idx]);
|
||||||
|
}
|
||||||
|
|
||||||
|
++num_rows;
|
||||||
|
if (num_rows == max_block_size)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return block;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void insertValue(IColumn * const column, const value_type_t type, const mongo::BSONElement & value)
|
||||||
|
{
|
||||||
|
switch (type)
|
||||||
|
{
|
||||||
|
case value_type_t::UInt8:
|
||||||
|
{
|
||||||
|
if (value.type() != mongo::Bool)
|
||||||
|
throw Exception{
|
||||||
|
"Type mismatch, expected Bool, got " + std::string{mongo::typeName(value.type())},
|
||||||
|
ErrorCodes::TYPE_MISMATCH
|
||||||
|
};
|
||||||
|
|
||||||
|
static_cast<ColumnFloat64 *>(column)->insert(value.boolean());
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case value_type_t::UInt16:
|
||||||
|
{
|
||||||
|
if (!value.isNumber())
|
||||||
|
throw Exception{
|
||||||
|
"Type mismatch, expected a number, got " + std::string{mongo::typeName(value.type())},
|
||||||
|
ErrorCodes::TYPE_MISMATCH
|
||||||
|
};
|
||||||
|
|
||||||
|
static_cast<ColumnUInt16 *>(column)->insert(value.numberInt());
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case value_type_t::UInt32:
|
||||||
|
{
|
||||||
|
if (!value.isNumber())
|
||||||
|
throw Exception{
|
||||||
|
"Type mismatch, expected a number, got " + std::string{mongo::typeName(value.type())},
|
||||||
|
ErrorCodes::TYPE_MISMATCH
|
||||||
|
};
|
||||||
|
|
||||||
|
static_cast<ColumnUInt32 *>(column)->insert(value.numberInt());
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case value_type_t::UInt64:
|
||||||
|
{
|
||||||
|
if (!value.isNumber())
|
||||||
|
throw Exception{
|
||||||
|
"Type mismatch, expected a number, got " + std::string{mongo::typeName(value.type())},
|
||||||
|
ErrorCodes::TYPE_MISMATCH
|
||||||
|
};
|
||||||
|
|
||||||
|
static_cast<ColumnUInt64 *>(column)->insert(value.numberLong());
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case value_type_t::Int8:
|
||||||
|
{
|
||||||
|
if (!value.isNumber())
|
||||||
|
throw Exception{
|
||||||
|
"Type mismatch, expected a number, got " + std::string{mongo::typeName(value.type())},
|
||||||
|
ErrorCodes::TYPE_MISMATCH
|
||||||
|
};
|
||||||
|
|
||||||
|
static_cast<ColumnInt8 *>(column)->insert(value.numberInt());
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case value_type_t::Int16:
|
||||||
|
{
|
||||||
|
if (!value.isNumber())
|
||||||
|
throw Exception{
|
||||||
|
"Type mismatch, expected a number, got " + std::string{mongo::typeName(value.type())},
|
||||||
|
ErrorCodes::TYPE_MISMATCH
|
||||||
|
};
|
||||||
|
|
||||||
|
static_cast<ColumnInt16 *>(column)->insert(value.numberInt());
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case value_type_t::Int32:
|
||||||
|
{
|
||||||
|
if (!value.isNumber())
|
||||||
|
throw Exception{
|
||||||
|
"Type mismatch, expected a number, got " + std::string{mongo::typeName(value.type())},
|
||||||
|
ErrorCodes::TYPE_MISMATCH
|
||||||
|
};
|
||||||
|
|
||||||
|
static_cast<ColumnInt32 *>(column)->insert(value.numberInt());
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case value_type_t::Int64:
|
||||||
|
{
|
||||||
|
if (!value.isNumber())
|
||||||
|
throw Exception{
|
||||||
|
"Type mismatch, expected a number, got " + std::string{mongo::typeName(value.type())},
|
||||||
|
ErrorCodes::TYPE_MISMATCH
|
||||||
|
};
|
||||||
|
|
||||||
|
static_cast<ColumnInt64 *>(column)->insert(value.numberLong());
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case value_type_t::Float32:
|
||||||
|
{
|
||||||
|
if (!value.isNumber())
|
||||||
|
throw Exception{
|
||||||
|
"Type mismatch, expected a number, got " + std::string{mongo::typeName(value.type())},
|
||||||
|
ErrorCodes::TYPE_MISMATCH
|
||||||
|
};
|
||||||
|
|
||||||
|
static_cast<ColumnFloat32 *>(column)->insert(value.number());
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case value_type_t::Float64:
|
||||||
|
{
|
||||||
|
if (!value.isNumber())
|
||||||
|
throw Exception{
|
||||||
|
"Type mismatch, expected a number, got " + std::string{mongo::typeName(value.type())},
|
||||||
|
ErrorCodes::TYPE_MISMATCH
|
||||||
|
};
|
||||||
|
|
||||||
|
static_cast<ColumnFloat64 *>(column)->insert(value.number());
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case value_type_t::String:
|
||||||
|
{
|
||||||
|
if (value.type() != mongo::String)
|
||||||
|
throw Exception{
|
||||||
|
"Type mismatch, expected String, got " + std::string{mongo::typeName(value.type())},
|
||||||
|
ErrorCodes::TYPE_MISMATCH
|
||||||
|
};
|
||||||
|
|
||||||
|
const auto string = value.String();
|
||||||
|
static_cast<ColumnString *>(column)->insertDataWithTerminatingZero(string.data(), string.size() + 1);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case value_type_t::Date:
|
||||||
|
{
|
||||||
|
if (value.type() != mongo::Date)
|
||||||
|
throw Exception{
|
||||||
|
"Type mismatch, expected Date, got " + std::string{mongo::typeName(value.type())},
|
||||||
|
ErrorCodes::TYPE_MISMATCH
|
||||||
|
};
|
||||||
|
|
||||||
|
static_cast<ColumnUInt16 *>(column)->insert(
|
||||||
|
UInt16{DateLUT::instance().toDayNum(value.date().toTimeT())});
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case value_type_t::DateTime:
|
||||||
|
{
|
||||||
|
if (value.type() != mongo::Date)
|
||||||
|
throw Exception{
|
||||||
|
"Type mismatch, expected Date, got " + std::string{mongo::typeName(value.type())},
|
||||||
|
ErrorCodes::TYPE_MISMATCH
|
||||||
|
};
|
||||||
|
|
||||||
|
static_cast<ColumnUInt32 *>(column)->insert(value.date().toTimeT());
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @todo insert default value from the dictionary attribute definition
|
||||||
|
static void insertDefaultValue(IColumn * const column, const value_type_t type)
|
||||||
|
{
|
||||||
|
switch (type)
|
||||||
|
{
|
||||||
|
case value_type_t::UInt8: static_cast<ColumnUInt8 *>(column)->insertDefault(); break;
|
||||||
|
case value_type_t::UInt16: static_cast<ColumnUInt16 *>(column)->insertDefault(); break;
|
||||||
|
case value_type_t::UInt32: static_cast<ColumnUInt32 *>(column)->insertDefault(); break;
|
||||||
|
case value_type_t::UInt64: static_cast<ColumnUInt64 *>(column)->insertDefault(); break;
|
||||||
|
case value_type_t::Int8: static_cast<ColumnInt8 *>(column)->insertDefault(); break;
|
||||||
|
case value_type_t::Int16: static_cast<ColumnInt16 *>(column)->insertDefault(); break;
|
||||||
|
case value_type_t::Int32: static_cast<ColumnInt32 *>(column)->insertDefault(); break;
|
||||||
|
case value_type_t::Int64: static_cast<ColumnInt64 *>(column)->insertDefault(); break;
|
||||||
|
case value_type_t::Float32: static_cast<ColumnFloat32 *>(column)->insertDefault(); break;
|
||||||
|
case value_type_t::Float64: static_cast<ColumnFloat64 *>(column)->insertDefault(); break;
|
||||||
|
case value_type_t::String: static_cast<ColumnString *>(column)->insertDefault(); break;
|
||||||
|
case value_type_t::Date: static_cast<ColumnUInt16 *>(column)->insertDefault(); break;
|
||||||
|
case value_type_t::DateTime: static_cast<ColumnUInt32 *>(column)->insertDefault(); break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
std::unique_ptr<mongo::DBClientCursor> cursor;
|
||||||
|
Block sample_block;
|
||||||
|
const std::size_t max_block_size;
|
||||||
|
std::vector<value_type_t> types;
|
||||||
|
std::vector<mongo::StringData> names;
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
128
dbms/include/DB/Dictionaries/MongoDBDictionarySource.h
Normal file
128
dbms/include/DB/Dictionaries/MongoDBDictionarySource.h
Normal file
@ -0,0 +1,128 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <DB/Dictionaries/IDictionarySource.h>
|
||||||
|
#include <DB/Dictionaries/MongoDBBlockInputStream.h>
|
||||||
|
#include <Poco/Util/AbstractConfiguration.h>
|
||||||
|
#include <mongo/client/dbclient.h>
|
||||||
|
|
||||||
|
|
||||||
|
namespace DB
|
||||||
|
{
|
||||||
|
|
||||||
|
/// Allows loading dictionaries from a MySQL database
|
||||||
|
class MongoDBDictionarySource final : public IDictionarySource
|
||||||
|
{
|
||||||
|
MongoDBDictionarySource(
|
||||||
|
const DictionaryStructure & dict_struct, const std::string & host, const std::string & port,
|
||||||
|
const std::string & user, const std::string & password,
|
||||||
|
const std::string & db, const std::string & collection,
|
||||||
|
const Block & sample_block, Context & context)
|
||||||
|
: dict_struct{dict_struct}, host{host}, port{port}, user{user}, password{password},
|
||||||
|
db{db}, collection{collection}, sample_block{sample_block}, context(context),
|
||||||
|
connection{true}
|
||||||
|
{
|
||||||
|
init();
|
||||||
|
|
||||||
|
connection.connect(host + ':' + port);
|
||||||
|
|
||||||
|
if (!user.empty())
|
||||||
|
{
|
||||||
|
std::string error;
|
||||||
|
if (!connection.auth(db, user, password, error))
|
||||||
|
throw DB::Exception{
|
||||||
|
"Could not authenticate to a MongoDB database " + db + " with provided credentials: " + error,
|
||||||
|
ErrorCodes::WRONG_PASSWORD
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
/// compose BSONObj containing all requested fields
|
||||||
|
mongo::BSONObjBuilder builder;
|
||||||
|
builder << "_id" << 0;
|
||||||
|
|
||||||
|
for (const auto & column : sample_block.getColumns())
|
||||||
|
builder << column.name << 1;
|
||||||
|
|
||||||
|
fields_to_query = builder.obj();
|
||||||
|
}
|
||||||
|
|
||||||
|
static void init()
|
||||||
|
{
|
||||||
|
static const auto mongo_init_status = mongo::client::initialize();
|
||||||
|
|
||||||
|
if (!mongo_init_status.isOK())
|
||||||
|
throw DB::Exception{
|
||||||
|
"mongo::client::initialize() failed: " + mongo_init_status.toString(),
|
||||||
|
ErrorCodes::MONGODB_INIT_FAILED
|
||||||
|
};
|
||||||
|
|
||||||
|
LOG_TRACE(&Logger::get("MongoDBDictionarySource"), "mongo::client::initialize() ok");
|
||||||
|
}
|
||||||
|
|
||||||
|
public:
|
||||||
|
MongoDBDictionarySource(
|
||||||
|
const DictionaryStructure & dict_struct, const Poco::Util::AbstractConfiguration & config,
|
||||||
|
const std::string & config_prefix, Block & sample_block, Context & context)
|
||||||
|
: MongoDBDictionarySource{
|
||||||
|
dict_struct,
|
||||||
|
config.getString(config_prefix + ".host"),
|
||||||
|
config.getString(config_prefix + ".port"),
|
||||||
|
config.getString(config_prefix + ".user", ""),
|
||||||
|
config.getString(config_prefix + ".password", ""),
|
||||||
|
config.getString(config_prefix + ".db", ""),
|
||||||
|
config.getString(config_prefix + ".collection"),
|
||||||
|
sample_block, context
|
||||||
|
}
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
MongoDBDictionarySource(const MongoDBDictionarySource & other)
|
||||||
|
: MongoDBDictionarySource{
|
||||||
|
other.dict_struct, other.host, other.port, other.user, other.password,
|
||||||
|
other.db, other.collection, other.sample_block, other.context
|
||||||
|
}
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
BlockInputStreamPtr loadAll() override
|
||||||
|
{
|
||||||
|
return new MongoDBBlockInputStream{
|
||||||
|
connection.query(db + '.' + collection, {}, 0, 0, &fields_to_query),
|
||||||
|
sample_block, 8192
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
bool supportsSelectiveLoad() const override { return true; }
|
||||||
|
|
||||||
|
BlockInputStreamPtr loadIds(const std::vector<std::uint64_t> & ids) override
|
||||||
|
{
|
||||||
|
return new MongoDBBlockInputStream{
|
||||||
|
connection.query(db + '.' + collection, {}, 0, 0, &fields_to_query),
|
||||||
|
sample_block, 8192
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
bool isModified() const override { return false; }
|
||||||
|
|
||||||
|
DictionarySourcePtr clone() const override { return std::make_unique<MongoDBDictionarySource>(*this); }
|
||||||
|
|
||||||
|
std::string toString() const override
|
||||||
|
{
|
||||||
|
return "MongoDB: " + db + '.' + collection + ',' + (user.empty() ? " " : " " + user + '@') + host + ':' + port;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
const DictionaryStructure dict_struct;
|
||||||
|
const std::string host;
|
||||||
|
const std::string port;
|
||||||
|
const std::string user;
|
||||||
|
const std::string password;
|
||||||
|
const std::string db;
|
||||||
|
const std::string collection;
|
||||||
|
Block sample_block;
|
||||||
|
Context & context;
|
||||||
|
|
||||||
|
mongo::DBClientConnection connection;
|
||||||
|
mongo::BSONObj fields_to_query;
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
@ -19,7 +19,7 @@ class MySQLDictionarySource final : public IDictionarySource
|
|||||||
public:
|
public:
|
||||||
MySQLDictionarySource(const DictionaryStructure & dict_struct,
|
MySQLDictionarySource(const DictionaryStructure & dict_struct,
|
||||||
const Poco::Util::AbstractConfiguration & config, const std::string & config_prefix,
|
const Poco::Util::AbstractConfiguration & config, const std::string & config_prefix,
|
||||||
Block & sample_block)
|
const Block & sample_block)
|
||||||
: dict_struct{dict_struct},
|
: dict_struct{dict_struct},
|
||||||
db{config.getString(config_prefix + ".db", "")},
|
db{config.getString(config_prefix + ".db", "")},
|
||||||
table{config.getString(config_prefix + ".table")},
|
table{config.getString(config_prefix + ".table")},
|
||||||
@ -78,7 +78,6 @@ public:
|
|||||||
private:
|
private:
|
||||||
Logger * log = &Logger::get("MySQLDictionarySource");
|
Logger * log = &Logger::get("MySQLDictionarySource");
|
||||||
|
|
||||||
|
|
||||||
static std::string quoteForLike(const std::string s)
|
static std::string quoteForLike(const std::string s)
|
||||||
{
|
{
|
||||||
std::string tmp;
|
std::string tmp;
|
||||||
|
@ -658,13 +658,13 @@ private:
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
/// Получить имя функции.
|
/// Получить имя функции.
|
||||||
String getName() const
|
String getName() const override
|
||||||
{
|
{
|
||||||
return name;
|
return name;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Получить типы результата по типам аргументов. Если функция неприменима для данных аргументов - кинуть исключение.
|
/// Получить типы результата по типам аргументов. Если функция неприменима для данных аргументов - кинуть исключение.
|
||||||
DataTypePtr getReturnType(const DataTypes & arguments) const
|
DataTypePtr getReturnType(const DataTypes & arguments) const override
|
||||||
{
|
{
|
||||||
if (arguments.size() != 2)
|
if (arguments.size() != 2)
|
||||||
throw Exception("Number of arguments for function " + getName() + " doesn't match: passed "
|
throw Exception("Number of arguments for function " + getName() + " doesn't match: passed "
|
||||||
@ -692,7 +692,7 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Выполнить функцию над блоком.
|
/// Выполнить функцию над блоком.
|
||||||
void execute(Block & block, const ColumnNumbers & arguments, size_t result)
|
void execute(Block & block, const ColumnNumbers & arguments, size_t result) override
|
||||||
{
|
{
|
||||||
if (!( executeLeftType<DataTypeDate>(block, arguments, result)
|
if (!( executeLeftType<DataTypeDate>(block, arguments, result)
|
||||||
|| executeLeftType<DataTypeDateTime>(block, arguments, result)
|
|| executeLeftType<DataTypeDateTime>(block, arguments, result)
|
||||||
@ -767,13 +767,13 @@ private:
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
/// Получить имя функции.
|
/// Получить имя функции.
|
||||||
String getName() const
|
String getName() const override
|
||||||
{
|
{
|
||||||
return name;
|
return name;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Получить типы результата по типам аргументов. Если функция неприменима для данных аргументов - кинуть исключение.
|
/// Получить типы результата по типам аргументов. Если функция неприменима для данных аргументов - кинуть исключение.
|
||||||
DataTypePtr getReturnType(const DataTypes & arguments) const
|
DataTypePtr getReturnType(const DataTypes & arguments) const override
|
||||||
{
|
{
|
||||||
if (arguments.size() != 1)
|
if (arguments.size() != 1)
|
||||||
throw Exception("Number of arguments for function " + getName() + " doesn't match: passed "
|
throw Exception("Number of arguments for function " + getName() + " doesn't match: passed "
|
||||||
@ -799,7 +799,7 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Выполнить функцию над блоком.
|
/// Выполнить функцию над блоком.
|
||||||
void execute(Block & block, const ColumnNumbers & arguments, size_t result)
|
void execute(Block & block, const ColumnNumbers & arguments, size_t result) override
|
||||||
{
|
{
|
||||||
if (!( executeType<UInt8>(block, arguments, result)
|
if (!( executeType<UInt8>(block, arguments, result)
|
||||||
|| executeType<UInt16>(block, arguments, result)
|
|| executeType<UInt16>(block, arguments, result)
|
||||||
|
@ -1,5 +1,7 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include <DB/Core/FieldVisitors.h>
|
||||||
|
|
||||||
#include <DB/DataTypes/DataTypeArray.h>
|
#include <DB/DataTypes/DataTypeArray.h>
|
||||||
#include <DB/DataTypes/DataTypesNumberFixed.h>
|
#include <DB/DataTypes/DataTypesNumberFixed.h>
|
||||||
#include <DB/DataTypes/DataTypeDate.h>
|
#include <DB/DataTypes/DataTypeDate.h>
|
||||||
@ -56,7 +58,7 @@ public:
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
/// Получить имя функции.
|
/// Получить имя функции.
|
||||||
String getName() const
|
String getName() const override
|
||||||
{
|
{
|
||||||
return name;
|
return name;
|
||||||
}
|
}
|
||||||
@ -159,7 +161,7 @@ private:
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
/// Получить тип результата по типам аргументов. Если функция неприменима для данных аргументов - кинуть исключение.
|
/// Получить тип результата по типам аргументов. Если функция неприменима для данных аргументов - кинуть исключение.
|
||||||
DataTypePtr getReturnType(const DataTypes & arguments) const
|
DataTypePtr getReturnType(const DataTypes & arguments) const override
|
||||||
{
|
{
|
||||||
if (arguments.empty())
|
if (arguments.empty())
|
||||||
throw Exception("Function array requires at least one argument.", ErrorCodes::NUMBER_OF_ARGUMENTS_DOESNT_MATCH);
|
throw Exception("Function array requires at least one argument.", ErrorCodes::NUMBER_OF_ARGUMENTS_DOESNT_MATCH);
|
||||||
@ -184,7 +186,7 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Выполнить функцию над блоком.
|
/// Выполнить функцию над блоком.
|
||||||
void execute(Block & block, const ColumnNumbers & arguments, size_t result)
|
void execute(Block & block, const ColumnNumbers & arguments, size_t result) override
|
||||||
{
|
{
|
||||||
const auto is_const = [&] {
|
const auto is_const = [&] {
|
||||||
for (const auto arg_num : arguments)
|
for (const auto arg_num : arguments)
|
||||||
@ -702,13 +704,13 @@ private:
|
|||||||
}
|
}
|
||||||
public:
|
public:
|
||||||
/// Получить имя функции.
|
/// Получить имя функции.
|
||||||
String getName() const
|
String getName() const override
|
||||||
{
|
{
|
||||||
return name;
|
return name;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Получить типы результата по типам аргументов. Если функция неприменима для данных аргументов - кинуть исключение.
|
/// Получить типы результата по типам аргументов. Если функция неприменима для данных аргументов - кинуть исключение.
|
||||||
DataTypePtr getReturnType(const DataTypes & arguments) const
|
DataTypePtr getReturnType(const DataTypes & arguments) const override
|
||||||
{
|
{
|
||||||
if (arguments.size() != 2)
|
if (arguments.size() != 2)
|
||||||
throw Exception("Number of arguments for function " + getName() + " doesn't match: passed "
|
throw Exception("Number of arguments for function " + getName() + " doesn't match: passed "
|
||||||
@ -727,7 +729,7 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Выполнить функцию над блоком.
|
/// Выполнить функцию над блоком.
|
||||||
void execute(Block & block, const ColumnNumbers & arguments, size_t result)
|
void execute(Block & block, const ColumnNumbers & arguments, size_t result) override
|
||||||
{
|
{
|
||||||
if (executeTuple(block, arguments, result))
|
if (executeTuple(block, arguments, result))
|
||||||
{
|
{
|
||||||
@ -795,13 +797,18 @@ struct IndexCount
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
template <typename T, typename IndexConv>
|
template <typename T, typename U, typename IndexConv>
|
||||||
struct ArrayIndexNumImpl
|
struct ArrayIndexNumImpl
|
||||||
{
|
{
|
||||||
|
#pragma GCC diagnostic push
|
||||||
|
#pragma GCC diagnostic ignored "-Wsign-compare"
|
||||||
|
|
||||||
/// compares `lhs` against `i`-th element of `rhs`
|
/// compares `lhs` against `i`-th element of `rhs`
|
||||||
static bool compare(const T & lhs, const PODArray<T> & rhs, const std::size_t i ) { return lhs == rhs[i]; }
|
static bool compare(const T & lhs, const PODArray<U> & rhs, const std::size_t i ) { return lhs == rhs[i]; }
|
||||||
/// compares `lhs against `rhs`, third argument unused
|
/// compares `lhs against `rhs`, third argument unused
|
||||||
static bool compare(const T & lhs, const T & rhs, std::size_t) { return lhs == rhs; }
|
static bool compare(const T & lhs, const U & rhs, std::size_t) { return lhs == rhs; }
|
||||||
|
|
||||||
|
#pragma GCC diagnostic pop
|
||||||
|
|
||||||
template <typename ScalarOrVector>
|
template <typename ScalarOrVector>
|
||||||
static void vector(
|
static void vector(
|
||||||
@ -921,6 +928,21 @@ private:
|
|||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
bool executeNumber(Block & block, const ColumnNumbers & arguments, size_t result)
|
bool executeNumber(Block & block, const ColumnNumbers & arguments, size_t result)
|
||||||
|
{
|
||||||
|
return executeNumberNumber<T, UInt8>(block, arguments, result)
|
||||||
|
|| executeNumberNumber<T, UInt16>(block, arguments, result)
|
||||||
|
|| executeNumberNumber<T, UInt32>(block, arguments, result)
|
||||||
|
|| executeNumberNumber<T, UInt64>(block, arguments, result)
|
||||||
|
|| executeNumberNumber<T, Int8>(block, arguments, result)
|
||||||
|
|| executeNumberNumber<T, Int16>(block, arguments, result)
|
||||||
|
|| executeNumberNumber<T, Int32>(block, arguments, result)
|
||||||
|
|| executeNumberNumber<T, Int64>(block, arguments, result)
|
||||||
|
|| executeNumberNumber<T, Float32>(block, arguments, result)
|
||||||
|
|| executeNumberNumber<T, Float64>(block, arguments, result);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T, typename U>
|
||||||
|
bool executeNumberNumber(Block & block, const ColumnNumbers & arguments, size_t result)
|
||||||
{
|
{
|
||||||
const ColumnArray * col_array = typeid_cast<const ColumnArray *>(&*block.getByPosition(arguments[0]).column);
|
const ColumnArray * col_array = typeid_cast<const ColumnArray *>(&*block.getByPosition(arguments[0]).column);
|
||||||
|
|
||||||
@ -934,24 +956,26 @@ private:
|
|||||||
|
|
||||||
const auto item_arg = block.getByPosition(arguments[1]).column.get();
|
const auto item_arg = block.getByPosition(arguments[1]).column.get();
|
||||||
|
|
||||||
if (const auto item_arg_const = typeid_cast<const ColumnConst<T> *>(item_arg))
|
if (const auto item_arg_const = typeid_cast<const ColumnConst<U> *>(item_arg))
|
||||||
{
|
{
|
||||||
const auto col_res = new ResultColumnType;
|
const auto col_res = new ResultColumnType;
|
||||||
ColumnPtr col_ptr{col_res};
|
ColumnPtr col_ptr{col_res};
|
||||||
block.getByPosition(result).column = col_ptr;
|
block.getByPosition(result).column = col_ptr;
|
||||||
|
|
||||||
ArrayIndexNumImpl<T, IndexConv>::vector(col_nested->getData(), col_array->getOffsets(),
|
ArrayIndexNumImpl<T, U, IndexConv>::vector(col_nested->getData(), col_array->getOffsets(),
|
||||||
item_arg_const->getData(), col_res->getData());
|
item_arg_const->getData(), col_res->getData());
|
||||||
}
|
}
|
||||||
else if (const auto item_arg_vector = typeid_cast<const ColumnVector<T> *>(item_arg))
|
else if (const auto item_arg_vector = typeid_cast<const ColumnVector<U> *>(item_arg))
|
||||||
{
|
{
|
||||||
const auto col_res = new ResultColumnType;
|
const auto col_res = new ResultColumnType;
|
||||||
ColumnPtr col_ptr{col_res};
|
ColumnPtr col_ptr{col_res};
|
||||||
block.getByPosition(result).column = col_ptr;
|
block.getByPosition(result).column = col_ptr;
|
||||||
|
|
||||||
ArrayIndexNumImpl<T, IndexConv>::vector(col_nested->getData(), col_array->getOffsets(),
|
ArrayIndexNumImpl<T, U, IndexConv>::vector(col_nested->getData(), col_array->getOffsets(),
|
||||||
item_arg_vector->getData(), col_res->getData());
|
item_arg_vector->getData(), col_res->getData());
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
return false;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -1010,7 +1034,7 @@ private:
|
|||||||
|
|
||||||
for (size_t i = 0, size = arr.size(); i < size; ++i)
|
for (size_t i = 0, size = arr.size(); i < size; ++i)
|
||||||
{
|
{
|
||||||
if (arr[i] == value)
|
if (apply_visitor(FieldVisitorAccurateEquals(), arr[i], value))
|
||||||
{
|
{
|
||||||
if (!IndexConv::apply(i, current))
|
if (!IndexConv::apply(i, current))
|
||||||
break;
|
break;
|
||||||
@ -1035,7 +1059,7 @@ private:
|
|||||||
const auto & value = (*item_arg)[row];
|
const auto & value = (*item_arg)[row];
|
||||||
for (size_t i = 0, size = arr.size(); i < size; ++i)
|
for (size_t i = 0, size = arr.size(); i < size; ++i)
|
||||||
{
|
{
|
||||||
if (arr[i] == value)
|
if (apply_visitor(FieldVisitorAccurateEquals(), arr[i], value))
|
||||||
{
|
{
|
||||||
if (!IndexConv::apply(i, data[row]))
|
if (!IndexConv::apply(i, data[row]))
|
||||||
break;
|
break;
|
||||||
@ -1050,13 +1074,13 @@ private:
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
/// Получить имя функции.
|
/// Получить имя функции.
|
||||||
String getName() const
|
String getName() const override
|
||||||
{
|
{
|
||||||
return name;
|
return name;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Получить типы результата по типам аргументов. Если функция неприменима для данных аргументов - кинуть исключение.
|
/// Получить типы результата по типам аргументов. Если функция неприменима для данных аргументов - кинуть исключение.
|
||||||
DataTypePtr getReturnType(const DataTypes & arguments) const
|
DataTypePtr getReturnType(const DataTypes & arguments) const override
|
||||||
{
|
{
|
||||||
if (arguments.size() != 2)
|
if (arguments.size() != 2)
|
||||||
throw Exception("Number of arguments for function " + getName() + " doesn't match: passed "
|
throw Exception("Number of arguments for function " + getName() + " doesn't match: passed "
|
||||||
@ -1067,7 +1091,8 @@ public:
|
|||||||
if (!array_type)
|
if (!array_type)
|
||||||
throw Exception("First argument for function " + getName() + " must be array.", ErrorCodes::ILLEGAL_TYPE_OF_ARGUMENT);
|
throw Exception("First argument for function " + getName() + " must be array.", ErrorCodes::ILLEGAL_TYPE_OF_ARGUMENT);
|
||||||
|
|
||||||
if (array_type->getNestedType()->getName() != arguments[1]->getName())
|
if (!(array_type->getNestedType()->behavesAsNumber() && arguments[1]->behavesAsNumber())
|
||||||
|
&& array_type->getNestedType()->getName() != arguments[1]->getName())
|
||||||
throw Exception("Type of array elements and second argument for function " + getName() + " must be same."
|
throw Exception("Type of array elements and second argument for function " + getName() + " must be same."
|
||||||
" Passed: " + arguments[0]->getName() + " and " + arguments[1]->getName() + ".", ErrorCodes::ILLEGAL_TYPE_OF_ARGUMENT);
|
" Passed: " + arguments[0]->getName() + " and " + arguments[1]->getName() + ".", ErrorCodes::ILLEGAL_TYPE_OF_ARGUMENT);
|
||||||
|
|
||||||
@ -1075,7 +1100,7 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Выполнить функцию над блоком.
|
/// Выполнить функцию над блоком.
|
||||||
void execute(Block & block, const ColumnNumbers & arguments, size_t result)
|
void execute(Block & block, const ColumnNumbers & arguments, size_t result) override
|
||||||
{
|
{
|
||||||
if (!(executeNumber<UInt8>(block, arguments, result)
|
if (!(executeNumber<UInt8>(block, arguments, result)
|
||||||
|| executeNumber<UInt16>(block, arguments, result)
|
|| executeNumber<UInt16>(block, arguments, result)
|
||||||
@ -1104,13 +1129,13 @@ public:
|
|||||||
static IFunction * create (const Context & context) { return new FunctionArrayEnumerate; }
|
static IFunction * create (const Context & context) { return new FunctionArrayEnumerate; }
|
||||||
|
|
||||||
/// Получить имя функции.
|
/// Получить имя функции.
|
||||||
String getName() const
|
String getName() const override
|
||||||
{
|
{
|
||||||
return name;
|
return name;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Получить типы результата по типам аргументов. Если функция неприменима для данных аргументов - кинуть исключение.
|
/// Получить типы результата по типам аргументов. Если функция неприменима для данных аргументов - кинуть исключение.
|
||||||
DataTypePtr getReturnType(const DataTypes & arguments) const
|
DataTypePtr getReturnType(const DataTypes & arguments) const override
|
||||||
{
|
{
|
||||||
if (arguments.size() != 1)
|
if (arguments.size() != 1)
|
||||||
throw Exception("Number of arguments for function " + getName() + " doesn't match: passed "
|
throw Exception("Number of arguments for function " + getName() + " doesn't match: passed "
|
||||||
@ -1125,7 +1150,7 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Выполнить функцию над блоком.
|
/// Выполнить функцию над блоком.
|
||||||
void execute(Block & block, const ColumnNumbers & arguments, size_t result)
|
void execute(Block & block, const ColumnNumbers & arguments, size_t result) override
|
||||||
{
|
{
|
||||||
if (const ColumnArray * array = typeid_cast<const ColumnArray *>(&*block.getByPosition(arguments[0]).column))
|
if (const ColumnArray * array = typeid_cast<const ColumnArray *>(&*block.getByPosition(arguments[0]).column))
|
||||||
{
|
{
|
||||||
@ -1180,13 +1205,13 @@ public:
|
|||||||
static IFunction * create(const Context & context) { return new FunctionArrayUniq; }
|
static IFunction * create(const Context & context) { return new FunctionArrayUniq; }
|
||||||
|
|
||||||
/// Получить имя функции.
|
/// Получить имя функции.
|
||||||
String getName() const
|
String getName() const override
|
||||||
{
|
{
|
||||||
return name;
|
return name;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Получить типы результата по типам аргументов. Если функция неприменима для данных аргументов - кинуть исключение.
|
/// Получить типы результата по типам аргументов. Если функция неприменима для данных аргументов - кинуть исключение.
|
||||||
DataTypePtr getReturnType(const DataTypes & arguments) const
|
DataTypePtr getReturnType(const DataTypes & arguments) const override
|
||||||
{
|
{
|
||||||
if (arguments.size() == 0)
|
if (arguments.size() == 0)
|
||||||
throw Exception("Number of arguments for function " + getName() + " doesn't match: passed "
|
throw Exception("Number of arguments for function " + getName() + " doesn't match: passed "
|
||||||
@ -1205,7 +1230,7 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Выполнить функцию над блоком.
|
/// Выполнить функцию над блоком.
|
||||||
void execute(Block & block, const ColumnNumbers & arguments, size_t result)
|
void execute(Block & block, const ColumnNumbers & arguments, size_t result) override
|
||||||
{
|
{
|
||||||
if (arguments.size() == 1 && executeConst(block, arguments, result))
|
if (arguments.size() == 1 && executeConst(block, arguments, result))
|
||||||
return;
|
return;
|
||||||
@ -1410,13 +1435,13 @@ public:
|
|||||||
static IFunction * create(const Context & context) { return new FunctionArrayEnumerateUniq; }
|
static IFunction * create(const Context & context) { return new FunctionArrayEnumerateUniq; }
|
||||||
|
|
||||||
/// Получить имя функции.
|
/// Получить имя функции.
|
||||||
String getName() const
|
String getName() const override
|
||||||
{
|
{
|
||||||
return name;
|
return name;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Получить типы результата по типам аргументов. Если функция неприменима для данных аргументов - кинуть исключение.
|
/// Получить типы результата по типам аргументов. Если функция неприменима для данных аргументов - кинуть исключение.
|
||||||
DataTypePtr getReturnType(const DataTypes & arguments) const
|
DataTypePtr getReturnType(const DataTypes & arguments) const override
|
||||||
{
|
{
|
||||||
if (arguments.size() == 0)
|
if (arguments.size() == 0)
|
||||||
throw Exception("Number of arguments for function " + getName() + " doesn't match: passed "
|
throw Exception("Number of arguments for function " + getName() + " doesn't match: passed "
|
||||||
@ -1435,7 +1460,7 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Выполнить функцию над блоком.
|
/// Выполнить функцию над блоком.
|
||||||
void execute(Block & block, const ColumnNumbers & arguments, size_t result)
|
void execute(Block & block, const ColumnNumbers & arguments, size_t result) override
|
||||||
{
|
{
|
||||||
if (arguments.size() == 1 && executeConst(block, arguments, result))
|
if (arguments.size() == 1 && executeConst(block, arguments, result))
|
||||||
return;
|
return;
|
||||||
@ -1655,12 +1680,12 @@ struct FunctionEmptyArray : public IFunction
|
|||||||
static IFunction * create(const Context & context) { return new FunctionEmptyArray; }
|
static IFunction * create(const Context & context) { return new FunctionEmptyArray; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
String getName() const
|
String getName() const override
|
||||||
{
|
{
|
||||||
return name;
|
return name;
|
||||||
}
|
}
|
||||||
|
|
||||||
DataTypePtr getReturnType(const DataTypes & arguments) const
|
DataTypePtr getReturnType(const DataTypes & arguments) const override
|
||||||
{
|
{
|
||||||
if (arguments.size() != 0)
|
if (arguments.size() != 0)
|
||||||
throw Exception("Number of arguments for function " + getName() + " doesn't match: passed "
|
throw Exception("Number of arguments for function " + getName() + " doesn't match: passed "
|
||||||
@ -1670,7 +1695,7 @@ private:
|
|||||||
return new DataTypeArray{new DataType{}};
|
return new DataTypeArray{new DataType{}};
|
||||||
}
|
}
|
||||||
|
|
||||||
void execute(Block & block, const ColumnNumbers & arguments, size_t result)
|
void execute(Block & block, const ColumnNumbers & arguments, size_t result) override
|
||||||
{
|
{
|
||||||
using UnderlyingColumnType = typename TypeToColumnType<typename DataType::FieldType>::ColumnType;
|
using UnderlyingColumnType = typename TypeToColumnType<typename DataType::FieldType>::ColumnType;
|
||||||
|
|
||||||
@ -1833,13 +1858,13 @@ public:
|
|||||||
static IFunction * create(const Context & context) { return new FunctionEmptyArrayToSingle; }
|
static IFunction * create(const Context & context) { return new FunctionEmptyArrayToSingle; }
|
||||||
|
|
||||||
/// Получить имя функции.
|
/// Получить имя функции.
|
||||||
String getName() const
|
String getName() const override
|
||||||
{
|
{
|
||||||
return name;
|
return name;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Получить типы результата по типам аргументов. Если функция неприменима для данных аргументов - кинуть исключение.
|
/// Получить типы результата по типам аргументов. Если функция неприменима для данных аргументов - кинуть исключение.
|
||||||
DataTypePtr getReturnType(const DataTypes & arguments) const
|
DataTypePtr getReturnType(const DataTypes & arguments) const override
|
||||||
{
|
{
|
||||||
if (arguments.size() != 1)
|
if (arguments.size() != 1)
|
||||||
throw Exception("Number of arguments for function " + getName() + " doesn't match: passed "
|
throw Exception("Number of arguments for function " + getName() + " doesn't match: passed "
|
||||||
@ -1855,7 +1880,7 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Выполнить функцию над блоком.
|
/// Выполнить функцию над блоком.
|
||||||
void execute(Block & block, const ColumnNumbers & arguments, size_t result)
|
void execute(Block & block, const ColumnNumbers & arguments, size_t result) override
|
||||||
{
|
{
|
||||||
if (executeConst(block, arguments, result))
|
if (executeConst(block, arguments, result))
|
||||||
return;
|
return;
|
||||||
|
@ -173,9 +173,9 @@ public:
|
|||||||
static constexpr auto name = "IPv6NumToString";
|
static constexpr auto name = "IPv6NumToString";
|
||||||
static IFunction * create(const Context & context) { return new FunctionIPv6NumToString; }
|
static IFunction * create(const Context & context) { return new FunctionIPv6NumToString; }
|
||||||
|
|
||||||
String getName() const { return name; }
|
String getName() const override { return name; }
|
||||||
|
|
||||||
DataTypePtr getReturnType(const DataTypes & arguments) const
|
DataTypePtr getReturnType(const DataTypes & arguments) const override
|
||||||
{
|
{
|
||||||
if (arguments.size() != 1)
|
if (arguments.size() != 1)
|
||||||
throw Exception("Number of arguments for function " + getName() + " doesn't match: passed "
|
throw Exception("Number of arguments for function " + getName() + " doesn't match: passed "
|
||||||
@ -259,9 +259,9 @@ public:
|
|||||||
static constexpr auto name = "cutIPv6";
|
static constexpr auto name = "cutIPv6";
|
||||||
static IFunction * create(const Context & context) { return new FunctionCutIPv6; }
|
static IFunction * create(const Context & context) { return new FunctionCutIPv6; }
|
||||||
|
|
||||||
String getName() const { return name; }
|
String getName() const override { return name; }
|
||||||
|
|
||||||
DataTypePtr getReturnType(const DataTypes & arguments) const
|
DataTypePtr getReturnType(const DataTypes & arguments) const override
|
||||||
{
|
{
|
||||||
if (arguments.size() != 3)
|
if (arguments.size() != 3)
|
||||||
throw Exception("Number of arguments for function " + getName() + " doesn't match: passed "
|
throw Exception("Number of arguments for function " + getName() + " doesn't match: passed "
|
||||||
@ -425,9 +425,9 @@ public:
|
|||||||
static constexpr auto name = "IPv6StringToNum";
|
static constexpr auto name = "IPv6StringToNum";
|
||||||
static IFunction * create(const Context & context) { return new FunctionIPv6StringToNum; }
|
static IFunction * create(const Context & context) { return new FunctionIPv6StringToNum; }
|
||||||
|
|
||||||
String getName() const { return name; }
|
String getName() const override { return name; }
|
||||||
|
|
||||||
DataTypePtr getReturnType(const DataTypes & arguments) const
|
DataTypePtr getReturnType(const DataTypes & arguments) const override
|
||||||
{
|
{
|
||||||
if (arguments.size() != 1)
|
if (arguments.size() != 1)
|
||||||
throw Exception("Number of arguments for function " + getName() + " doesn't match: passed "
|
throw Exception("Number of arguments for function " + getName() + " doesn't match: passed "
|
||||||
@ -594,7 +594,7 @@ public:
|
|||||||
memcpy(dst, tmp, sizeof(tmp));
|
memcpy(dst, tmp, sizeof(tmp));
|
||||||
}
|
}
|
||||||
|
|
||||||
void execute(Block & block, const ColumnNumbers & arguments, size_t result)
|
void execute(Block & block, const ColumnNumbers & arguments, size_t result) override
|
||||||
{
|
{
|
||||||
const ColumnPtr & column = block.getByPosition(arguments[0]).column;
|
const ColumnPtr & column = block.getByPosition(arguments[0]).column;
|
||||||
|
|
||||||
@ -642,13 +642,13 @@ public:
|
|||||||
static IFunction * create(const Context & context) { return new FunctionIPv4NumToString; }
|
static IFunction * create(const Context & context) { return new FunctionIPv4NumToString; }
|
||||||
|
|
||||||
/// Получить имя функции.
|
/// Получить имя функции.
|
||||||
String getName() const
|
String getName() const override
|
||||||
{
|
{
|
||||||
return name;
|
return name;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Получить тип результата по типам аргументов. Если функция неприменима для данных аргументов - кинуть исключение.
|
/// Получить тип результата по типам аргументов. Если функция неприменима для данных аргументов - кинуть исключение.
|
||||||
DataTypePtr getReturnType(const DataTypes & arguments) const
|
DataTypePtr getReturnType(const DataTypes & arguments) const override
|
||||||
{
|
{
|
||||||
if (arguments.size() != 1)
|
if (arguments.size() != 1)
|
||||||
throw Exception("Number of arguments for function " + getName() + " doesn't match: passed "
|
throw Exception("Number of arguments for function " + getName() + " doesn't match: passed "
|
||||||
@ -697,7 +697,7 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Выполнить функцию над блоком.
|
/// Выполнить функцию над блоком.
|
||||||
void execute(Block & block, const ColumnNumbers & arguments, size_t result)
|
void execute(Block & block, const ColumnNumbers & arguments, size_t result) override
|
||||||
{
|
{
|
||||||
const ColumnPtr column = block.getByPosition(arguments[0]).column;
|
const ColumnPtr column = block.getByPosition(arguments[0]).column;
|
||||||
|
|
||||||
@ -747,13 +747,13 @@ public:
|
|||||||
static IFunction * create(const Context & context) { return new FunctionIPv4StringToNum; }
|
static IFunction * create(const Context & context) { return new FunctionIPv4StringToNum; }
|
||||||
|
|
||||||
/// Получить имя функции.
|
/// Получить имя функции.
|
||||||
String getName() const
|
String getName() const override
|
||||||
{
|
{
|
||||||
return name;
|
return name;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Получить тип результата по типам аргументов. Если функция неприменима для данных аргументов - кинуть исключение.
|
/// Получить тип результата по типам аргументов. Если функция неприменима для данных аргументов - кинуть исключение.
|
||||||
DataTypePtr getReturnType(const DataTypes & arguments) const
|
DataTypePtr getReturnType(const DataTypes & arguments) const override
|
||||||
{
|
{
|
||||||
if (arguments.size() != 1)
|
if (arguments.size() != 1)
|
||||||
throw Exception("Number of arguments for function " + getName() + " doesn't match: passed "
|
throw Exception("Number of arguments for function " + getName() + " doesn't match: passed "
|
||||||
@ -796,7 +796,7 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Выполнить функцию над блоком.
|
/// Выполнить функцию над блоком.
|
||||||
void execute(Block & block, const ColumnNumbers & arguments, size_t result)
|
void execute(Block & block, const ColumnNumbers & arguments, size_t result) override
|
||||||
{
|
{
|
||||||
const ColumnPtr column = block.getByPosition(arguments[0]).column;
|
const ColumnPtr column = block.getByPosition(arguments[0]).column;
|
||||||
|
|
||||||
@ -838,13 +838,13 @@ public:
|
|||||||
static IFunction * create(const Context & context) { return new FunctionIPv4NumToStringClassC; }
|
static IFunction * create(const Context & context) { return new FunctionIPv4NumToStringClassC; }
|
||||||
|
|
||||||
/// Получить имя функции.
|
/// Получить имя функции.
|
||||||
String getName() const
|
String getName() const override
|
||||||
{
|
{
|
||||||
return name;
|
return name;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Получить тип результата по типам аргументов. Если функция неприменима для данных аргументов - кинуть исключение.
|
/// Получить тип результата по типам аргументов. Если функция неприменима для данных аргументов - кинуть исключение.
|
||||||
DataTypePtr getReturnType(const DataTypes & arguments) const
|
DataTypePtr getReturnType(const DataTypes & arguments) const override
|
||||||
{
|
{
|
||||||
if (arguments.size() != 1)
|
if (arguments.size() != 1)
|
||||||
throw Exception("Number of arguments for function " + getName() + " doesn't match: passed "
|
throw Exception("Number of arguments for function " + getName() + " doesn't match: passed "
|
||||||
@ -896,7 +896,7 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Выполнить функцию над блоком.
|
/// Выполнить функцию над блоком.
|
||||||
void execute(Block & block, const ColumnNumbers & arguments, size_t result)
|
void execute(Block & block, const ColumnNumbers & arguments, size_t result) override
|
||||||
{
|
{
|
||||||
const ColumnPtr column = block.getByPosition(arguments[0]).column;
|
const ColumnPtr column = block.getByPosition(arguments[0]).column;
|
||||||
|
|
||||||
@ -945,9 +945,9 @@ public:
|
|||||||
static constexpr auto name = "IPv4ToIPv6";
|
static constexpr auto name = "IPv4ToIPv6";
|
||||||
static IFunction * create(const Context & context) { return new FunctionIPv4ToIPv6; }
|
static IFunction * create(const Context & context) { return new FunctionIPv4ToIPv6; }
|
||||||
|
|
||||||
String getName() const { return name; }
|
String getName() const override { return name; }
|
||||||
|
|
||||||
DataTypePtr getReturnType(const DataTypes & arguments) const
|
DataTypePtr getReturnType(const DataTypes & arguments) const override
|
||||||
{
|
{
|
||||||
if (arguments.size() != 1)
|
if (arguments.size() != 1)
|
||||||
throw Exception("Number of arguments for function " + getName() + " doesn't match: passed "
|
throw Exception("Number of arguments for function " + getName() + " doesn't match: passed "
|
||||||
@ -1010,13 +1010,13 @@ public:
|
|||||||
static IFunction * create(const Context & context) { return new FunctionHex; }
|
static IFunction * create(const Context & context) { return new FunctionHex; }
|
||||||
|
|
||||||
/// Получить имя функции.
|
/// Получить имя функции.
|
||||||
String getName() const
|
String getName() const override
|
||||||
{
|
{
|
||||||
return name;
|
return name;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Получить тип результата по типам аргументов. Если функция неприменима для данных аргументов - кинуть исключение.
|
/// Получить тип результата по типам аргументов. Если функция неприменима для данных аргументов - кинуть исключение.
|
||||||
DataTypePtr getReturnType(const DataTypes & arguments) const
|
DataTypePtr getReturnType(const DataTypes & arguments) const override
|
||||||
{
|
{
|
||||||
if (arguments.size() != 1)
|
if (arguments.size() != 1)
|
||||||
throw Exception("Number of arguments for function " + getName() + " doesn't match: passed "
|
throw Exception("Number of arguments for function " + getName() + " doesn't match: passed "
|
||||||
@ -1231,7 +1231,7 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Выполнить функцию над блоком.
|
/// Выполнить функцию над блоком.
|
||||||
void execute(Block & block, const ColumnNumbers & arguments, size_t result)
|
void execute(Block & block, const ColumnNumbers & arguments, size_t result) override
|
||||||
{
|
{
|
||||||
const IColumn * column = &*block.getByPosition(arguments[0]).column;
|
const IColumn * column = &*block.getByPosition(arguments[0]).column;
|
||||||
ColumnPtr & res_column = block.getByPosition(result).column;
|
ColumnPtr & res_column = block.getByPosition(result).column;
|
||||||
@ -1258,13 +1258,13 @@ public:
|
|||||||
static IFunction * create(const Context & context) { return new FunctionUnhex; }
|
static IFunction * create(const Context & context) { return new FunctionUnhex; }
|
||||||
|
|
||||||
/// Получить имя функции.
|
/// Получить имя функции.
|
||||||
String getName() const
|
String getName() const override
|
||||||
{
|
{
|
||||||
return name;
|
return name;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Получить тип результата по типам аргументов. Если функция неприменима для данных аргументов - кинуть исключение.
|
/// Получить тип результата по типам аргументов. Если функция неприменима для данных аргументов - кинуть исключение.
|
||||||
DataTypePtr getReturnType(const DataTypes & arguments) const
|
DataTypePtr getReturnType(const DataTypes & arguments) const override
|
||||||
{
|
{
|
||||||
if (arguments.size() != 1)
|
if (arguments.size() != 1)
|
||||||
throw Exception("Number of arguments for function " + getName() + " doesn't match: passed "
|
throw Exception("Number of arguments for function " + getName() + " doesn't match: passed "
|
||||||
@ -1303,7 +1303,7 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Выполнить функцию над блоком.
|
/// Выполнить функцию над блоком.
|
||||||
void execute(Block & block, const ColumnNumbers & arguments, size_t result)
|
void execute(Block & block, const ColumnNumbers & arguments, size_t result) override
|
||||||
{
|
{
|
||||||
const ColumnPtr column = block.getByPosition(arguments[0]).column;
|
const ColumnPtr column = block.getByPosition(arguments[0]).column;
|
||||||
|
|
||||||
@ -1366,13 +1366,13 @@ public:
|
|||||||
static IFunction * create(const Context & context) { return new FunctionBitmaskToArray; }
|
static IFunction * create(const Context & context) { return new FunctionBitmaskToArray; }
|
||||||
|
|
||||||
/// Получить имя функции.
|
/// Получить имя функции.
|
||||||
String getName() const
|
String getName() const override
|
||||||
{
|
{
|
||||||
return name;
|
return name;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Получить тип результата по типам аргументов. Если функция неприменима для данных аргументов - кинуть исключение.
|
/// Получить тип результата по типам аргументов. Если функция неприменима для данных аргументов - кинуть исключение.
|
||||||
DataTypePtr getReturnType(const DataTypes & arguments) const
|
DataTypePtr getReturnType(const DataTypes & arguments) const override
|
||||||
{
|
{
|
||||||
if (arguments.size() != 1)
|
if (arguments.size() != 1)
|
||||||
throw Exception("Number of arguments for function " + getName() + " doesn't match: passed "
|
throw Exception("Number of arguments for function " + getName() + " doesn't match: passed "
|
||||||
@ -1450,7 +1450,7 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Выполнить функцию над блоком.
|
/// Выполнить функцию над блоком.
|
||||||
void execute(Block & block, const ColumnNumbers & arguments, size_t result)
|
void execute(Block & block, const ColumnNumbers & arguments, size_t result) override
|
||||||
{
|
{
|
||||||
const IColumn * in_column = &*block.getByPosition(arguments[0]).column;
|
const IColumn * in_column = &*block.getByPosition(arguments[0]).column;
|
||||||
ColumnPtr & out_column = block.getByPosition(result).column;
|
ColumnPtr & out_column = block.getByPosition(result).column;
|
||||||
@ -1478,13 +1478,13 @@ public:
|
|||||||
static IFunction * create(const Context & context) { return new FunctionToStringCutToZero; }
|
static IFunction * create(const Context & context) { return new FunctionToStringCutToZero; }
|
||||||
|
|
||||||
/// Получить имя функции.
|
/// Получить имя функции.
|
||||||
String getName() const
|
String getName() const override
|
||||||
{
|
{
|
||||||
return name;
|
return name;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Получить тип результата по типам аргументов. Если функция неприменима для данных аргументов - кинуть исключение.
|
/// Получить тип результата по типам аргументов. Если функция неприменима для данных аргументов - кинуть исключение.
|
||||||
DataTypePtr getReturnType(const DataTypes & arguments) const
|
DataTypePtr getReturnType(const DataTypes & arguments) const override
|
||||||
{
|
{
|
||||||
if (arguments.size() != 1)
|
if (arguments.size() != 1)
|
||||||
throw Exception("Number of arguments for function " + getName() + " doesn't match: passed "
|
throw Exception("Number of arguments for function " + getName() + " doesn't match: passed "
|
||||||
@ -1600,7 +1600,7 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Выполнить функцию над блоком.
|
/// Выполнить функцию над блоком.
|
||||||
void execute(Block & block, const ColumnNumbers & arguments, size_t result)
|
void execute(Block & block, const ColumnNumbers & arguments, size_t result) override
|
||||||
{
|
{
|
||||||
const IColumn * column = &*block.getByPosition(arguments[0]).column;
|
const IColumn * column = &*block.getByPosition(arguments[0]).column;
|
||||||
ColumnPtr & res_column = block.getByPosition(result).column;
|
ColumnPtr & res_column = block.getByPosition(result).column;
|
||||||
|
@ -10,7 +10,9 @@
|
|||||||
#include <DB/DataTypes/DataTypeDate.h>
|
#include <DB/DataTypes/DataTypeDate.h>
|
||||||
#include <DB/DataTypes/DataTypeString.h>
|
#include <DB/DataTypes/DataTypeString.h>
|
||||||
#include <DB/DataTypes/DataTypeFixedString.h>
|
#include <DB/DataTypes/DataTypeFixedString.h>
|
||||||
|
#include <DB/DataTypes/DataTypeTuple.h>
|
||||||
|
|
||||||
|
#include <DB/Functions/FunctionsLogical.h>
|
||||||
#include <DB/Functions/IFunction.h>
|
#include <DB/Functions/IFunction.h>
|
||||||
|
|
||||||
|
|
||||||
@ -384,6 +386,14 @@ template <typename A, typename B>
|
|||||||
struct StringComparisonImpl<NotEqualsOp<A, B>> : StringEqualsImpl<false> {};
|
struct StringComparisonImpl<NotEqualsOp<A, B>> : StringEqualsImpl<false> {};
|
||||||
|
|
||||||
|
|
||||||
|
struct NameEquals { static constexpr auto name = "equals"; };
|
||||||
|
struct NameNotEquals { static constexpr auto name = "notEquals"; };
|
||||||
|
struct NameLess { static constexpr auto name = "less"; };
|
||||||
|
struct NameGreater { static constexpr auto name = "greater"; };
|
||||||
|
struct NameLessOrEquals { static constexpr auto name = "lessOrEquals"; };
|
||||||
|
struct NameGreaterOrEquals { static constexpr auto name = "greaterOrEquals"; };
|
||||||
|
|
||||||
|
|
||||||
template <
|
template <
|
||||||
template <typename, typename> class Op,
|
template <typename, typename> class Op,
|
||||||
typename Name>
|
typename Name>
|
||||||
@ -620,15 +630,117 @@ private:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void executeTuple(Block & block, size_t result, const IColumn * c0, const IColumn * c1)
|
||||||
|
{
|
||||||
|
/** Сравнивать кортежи будем лексикографически. Это делается следующим образом:
|
||||||
|
* x == y : x1 == y1 && x2 == y2 ...
|
||||||
|
* x != y : x1 != y1 || x2 != y2 ...
|
||||||
|
*
|
||||||
|
* x < y: x1 < y1 || (x1 == y1 && (x2 < y2 || (x2 == y2 ... && xn < yn))
|
||||||
|
* x > y: x1 > y1 || (x1 == y1 && (x2 > y2 || (x2 == y2 ... && xn > yn))
|
||||||
|
* x <= y: x1 < y1 || (x1 == y1 && (x2 < y2 || (x2 == y2 ... && xn <= yn))
|
||||||
|
*
|
||||||
|
* Рекурсивная запись:
|
||||||
|
* x <= y: x1 < y1 || (x1 == y1 && x_tail <= y_tail)
|
||||||
|
*
|
||||||
|
* x >= y: x1 > y1 || (x1 == y1 && (x2 > y2 || (x2 == y2 ... && xn >= yn))
|
||||||
|
*/
|
||||||
|
|
||||||
|
auto x = static_cast<const ColumnTuple *>(c0);
|
||||||
|
auto y = static_cast<const ColumnTuple *>(c1);
|
||||||
|
const size_t tuple_size = x->getData().columns();
|
||||||
|
|
||||||
|
if (0 == tuple_size)
|
||||||
|
throw Exception("Comparison of zero-sized tuples is not implemented.", ErrorCodes::NOT_IMPLEMENTED);
|
||||||
|
|
||||||
|
executeTupleImpl(block, result, x, y, tuple_size);
|
||||||
|
}
|
||||||
|
|
||||||
|
void executeTupleImpl(Block & block, size_t result, const ColumnTuple * x, const ColumnTuple * y, size_t tuple_size);
|
||||||
|
|
||||||
|
template <typename ComparisonFunction, typename ConvolutionFunction>
|
||||||
|
void executeTupleEqualityImpl(Block & block, size_t result, const ColumnTuple * x, const ColumnTuple * y, size_t tuple_size)
|
||||||
|
{
|
||||||
|
ComparisonFunction func_compare;
|
||||||
|
ConvolutionFunction func_convolution;
|
||||||
|
|
||||||
|
Block tmp_block;
|
||||||
|
for (size_t i = 0; i < tuple_size; ++i)
|
||||||
|
{
|
||||||
|
tmp_block.insert(x->getData().getByPosition(i));
|
||||||
|
tmp_block.insert(y->getData().getByPosition(i));
|
||||||
|
|
||||||
|
/// Сравнение элементов.
|
||||||
|
tmp_block.insert({ nullptr, new DataTypeUInt8, "" });
|
||||||
|
func_compare.execute(tmp_block, {i * 3, i * 3 + 1}, i * 3 + 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Логическая свёртка.
|
||||||
|
tmp_block.insert({ nullptr, new DataTypeUInt8, "" });
|
||||||
|
|
||||||
|
ColumnNumbers convolution_args(tuple_size);
|
||||||
|
for (size_t i = 0; i < tuple_size; ++i)
|
||||||
|
convolution_args[i] = i * 3 + 2;
|
||||||
|
|
||||||
|
func_convolution.execute(tmp_block, convolution_args, tuple_size * 3);
|
||||||
|
block.getByPosition(result).column = tmp_block.getByPosition(tuple_size * 3).column;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename HeadComparisonFunction, typename TailComparisonFunction>
|
||||||
|
void executeTupleLessGreaterImpl(Block & block, size_t result, const ColumnTuple * x, const ColumnTuple * y, size_t tuple_size)
|
||||||
|
{
|
||||||
|
HeadComparisonFunction func_compare_head;
|
||||||
|
TailComparisonFunction func_compare_tail;
|
||||||
|
FunctionAnd func_and;
|
||||||
|
FunctionOr func_or;
|
||||||
|
FunctionComparison<EqualsOp, NameEquals> func_equals;
|
||||||
|
|
||||||
|
Block tmp_block;
|
||||||
|
|
||||||
|
/// Попарное сравнение на неравенство всех элементов; на равенство всех элементов кроме последнего.
|
||||||
|
for (size_t i = 0; i < tuple_size; ++i)
|
||||||
|
{
|
||||||
|
tmp_block.insert(x->getData().getByPosition(i));
|
||||||
|
tmp_block.insert(y->getData().getByPosition(i));
|
||||||
|
|
||||||
|
tmp_block.insert({ nullptr, new DataTypeUInt8, "" });
|
||||||
|
|
||||||
|
if (i + 1 != tuple_size)
|
||||||
|
{
|
||||||
|
func_compare_head.execute(tmp_block, {i * 4, i * 4 + 1}, i * 4 + 2);
|
||||||
|
|
||||||
|
tmp_block.insert({ nullptr, new DataTypeUInt8, "" });
|
||||||
|
func_equals.execute(tmp_block, {i * 4, i * 4 + 1}, i * 4 + 3);
|
||||||
|
|
||||||
|
}
|
||||||
|
else
|
||||||
|
func_compare_tail.execute(tmp_block, {i * 4, i * 4 + 1}, i * 4 + 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Комбинирование. Сложный код - сделайте рисунок. Можно заменить на рекурсивное сравнение кортежей.
|
||||||
|
size_t i = tuple_size - 1;
|
||||||
|
while (i > 0)
|
||||||
|
{
|
||||||
|
tmp_block.insert({ nullptr, new DataTypeUInt8, "" });
|
||||||
|
func_and.execute(tmp_block, { tmp_block.columns() - 2, (i - 1) * 4 + 3 }, tmp_block.columns() - 1);
|
||||||
|
tmp_block.insert({ nullptr, new DataTypeUInt8, "" });
|
||||||
|
func_or.execute(tmp_block, { tmp_block.columns() - 2, (i - 1) * 4 + 2 }, tmp_block.columns() - 1);
|
||||||
|
--i;
|
||||||
|
}
|
||||||
|
|
||||||
|
block.getByPosition(result).column = tmp_block.getByPosition(tmp_block.columns() - 1).column;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
/// Получить имя функции.
|
/// Получить имя функции.
|
||||||
String getName() const
|
String getName() const override
|
||||||
{
|
{
|
||||||
return name;
|
return name;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Получить типы результата по типам аргументов. Если функция неприменима для данных аргументов - кинуть исключение.
|
/// Получить типы результата по типам аргументов. Если функция неприменима для данных аргументов - кинуть исключение.
|
||||||
DataTypePtr getReturnType(const DataTypes & arguments) const
|
DataTypePtr getReturnType(const DataTypes & arguments) const override
|
||||||
{
|
{
|
||||||
if (arguments.size() != 2)
|
if (arguments.size() != 2)
|
||||||
throw Exception("Number of arguments for function " + getName() + " doesn't match: passed "
|
throw Exception("Number of arguments for function " + getName() + " doesn't match: passed "
|
||||||
@ -639,23 +751,27 @@ public:
|
|||||||
bool left_is_date_time = false;
|
bool left_is_date_time = false;
|
||||||
bool left_is_string = false;
|
bool left_is_string = false;
|
||||||
bool left_is_fixed_string = false;
|
bool left_is_fixed_string = false;
|
||||||
|
const DataTypeTuple * left_tuple = nullptr;
|
||||||
|
|
||||||
false
|
false
|
||||||
|| (left_is_date = typeid_cast<const DataTypeDate *>(arguments[0].get()))
|
|| (left_is_date = typeid_cast<const DataTypeDate *>(arguments[0].get()))
|
||||||
|| (left_is_date_time = typeid_cast<const DataTypeDateTime *>(arguments[0].get()))
|
|| (left_is_date_time = typeid_cast<const DataTypeDateTime *>(arguments[0].get()))
|
||||||
|| (left_is_string = typeid_cast<const DataTypeString *>(arguments[0].get()))
|
|| (left_is_string = typeid_cast<const DataTypeString *>(arguments[0].get()))
|
||||||
|| (left_is_fixed_string = typeid_cast<const DataTypeFixedString *>(arguments[0].get()));
|
|| (left_is_fixed_string = typeid_cast<const DataTypeFixedString *>(arguments[0].get()))
|
||||||
|
|| (left_tuple = typeid_cast<const DataTypeTuple *>(arguments[0].get()));
|
||||||
|
|
||||||
bool right_is_date = false;
|
bool right_is_date = false;
|
||||||
bool right_is_date_time = false;
|
bool right_is_date_time = false;
|
||||||
bool right_is_string = false;
|
bool right_is_string = false;
|
||||||
bool right_is_fixed_string = false;
|
bool right_is_fixed_string = false;
|
||||||
|
const DataTypeTuple * right_tuple = nullptr;
|
||||||
|
|
||||||
false
|
false
|
||||||
|| (right_is_date = typeid_cast<const DataTypeDate *>(arguments[1].get()))
|
|| (right_is_date = typeid_cast<const DataTypeDate *>(arguments[1].get()))
|
||||||
|| (right_is_date_time = typeid_cast<const DataTypeDateTime *>(arguments[1].get()))
|
|| (right_is_date_time = typeid_cast<const DataTypeDateTime *>(arguments[1].get()))
|
||||||
|| (right_is_string = typeid_cast<const DataTypeString *>(arguments[1].get()))
|
|| (right_is_string = typeid_cast<const DataTypeString *>(arguments[1].get()))
|
||||||
|| (right_is_fixed_string = typeid_cast<const DataTypeFixedString *>(arguments[1].get()));
|
|| (right_is_fixed_string = typeid_cast<const DataTypeFixedString *>(arguments[1].get()))
|
||||||
|
|| (right_tuple = typeid_cast<const DataTypeTuple *>(arguments[1].get()));
|
||||||
|
|
||||||
if (!( (arguments[0]->behavesAsNumber() && arguments[1]->behavesAsNumber())
|
if (!( (arguments[0]->behavesAsNumber() && arguments[1]->behavesAsNumber())
|
||||||
|| ((left_is_string || left_is_fixed_string) && (right_is_string || right_is_fixed_string))
|
|| ((left_is_string || left_is_fixed_string) && (right_is_string || right_is_fixed_string))
|
||||||
@ -664,15 +780,23 @@ public:
|
|||||||
|| (left_is_string && right_is_date)
|
|| (left_is_string && right_is_date)
|
||||||
|| (left_is_date_time && right_is_date_time)
|
|| (left_is_date_time && right_is_date_time)
|
||||||
|| (left_is_date_time && right_is_string)
|
|| (left_is_date_time && right_is_string)
|
||||||
|| (left_is_string && right_is_date_time)))
|
|| (left_is_string && right_is_date_time)
|
||||||
|
|| (left_tuple && right_tuple && left_tuple->getElements().size() == right_tuple->getElements().size())))
|
||||||
throw Exception("Illegal types of arguments (" + arguments[0]->getName() + ", " + arguments[1]->getName() + ")"
|
throw Exception("Illegal types of arguments (" + arguments[0]->getName() + ", " + arguments[1]->getName() + ")"
|
||||||
" of function " + getName(), ErrorCodes::ILLEGAL_TYPE_OF_ARGUMENT);
|
" of function " + getName(), ErrorCodes::ILLEGAL_TYPE_OF_ARGUMENT);
|
||||||
|
|
||||||
|
if (left_tuple && right_tuple)
|
||||||
|
{
|
||||||
|
size_t size = left_tuple->getElements().size();
|
||||||
|
for (size_t i = 0; i < size; ++i)
|
||||||
|
getReturnType({ left_tuple->getElements()[i], right_tuple->getElements()[i] });
|
||||||
|
}
|
||||||
|
|
||||||
return new DataTypeUInt8;
|
return new DataTypeUInt8;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Выполнить функцию над блоком.
|
/// Выполнить функцию над блоком.
|
||||||
void execute(Block & block, const ColumnNumbers & arguments, size_t result)
|
void execute(Block & block, const ColumnNumbers & arguments, size_t result) override
|
||||||
{
|
{
|
||||||
const IColumn * col_left_untyped = block.getByPosition(arguments[0]).column.get();
|
const IColumn * col_left_untyped = block.getByPosition(arguments[0]).column.get();
|
||||||
const IColumn * col_right_untyped = block.getByPosition(arguments[1]).column.get();
|
const IColumn * col_right_untyped = block.getByPosition(arguments[1]).column.get();
|
||||||
@ -696,25 +820,25 @@ public:
|
|||||||
+ " of first argument of function " + getName(),
|
+ " of first argument of function " + getName(),
|
||||||
ErrorCodes::ILLEGAL_COLUMN);
|
ErrorCodes::ILLEGAL_COLUMN);
|
||||||
}
|
}
|
||||||
else if (!left_is_num && !right_is_num)
|
|
||||||
{
|
|
||||||
executeString(block, result, col_left_untyped, col_right_untyped);
|
|
||||||
}
|
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
executeDateOrDateTimeWithConstString(block, result, col_left_untyped, col_right_untyped, left_is_num, right_is_num);
|
if (typeid_cast<const ColumnTuple *>(col_left_untyped))
|
||||||
|
{
|
||||||
|
executeTuple(block, result, col_left_untyped, col_right_untyped);
|
||||||
|
}
|
||||||
|
else if (!left_is_num && !right_is_num)
|
||||||
|
{
|
||||||
|
executeString(block, result, col_left_untyped, col_right_untyped);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
executeDateOrDateTimeWithConstString(block, result, col_left_untyped, col_right_untyped, left_is_num, right_is_num);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
struct NameEquals { static constexpr auto name = "equals"; };
|
|
||||||
struct NameNotEquals { static constexpr auto name = "notEquals"; };
|
|
||||||
struct NameLess { static constexpr auto name = "less"; };
|
|
||||||
struct NameGreater { static constexpr auto name = "greater"; };
|
|
||||||
struct NameLessOrEquals { static constexpr auto name = "lessOrEquals"; };
|
|
||||||
struct NameGreaterOrEquals { static constexpr auto name = "greaterOrEquals"; };
|
|
||||||
|
|
||||||
typedef FunctionComparison<EqualsOp, NameEquals> FunctionEquals;
|
typedef FunctionComparison<EqualsOp, NameEquals> FunctionEquals;
|
||||||
typedef FunctionComparison<NotEqualsOp, NameNotEquals> FunctionNotEquals;
|
typedef FunctionComparison<NotEqualsOp, NameNotEquals> FunctionNotEquals;
|
||||||
typedef FunctionComparison<LessOp, NameLess> FunctionLess;
|
typedef FunctionComparison<LessOp, NameLess> FunctionLess;
|
||||||
@ -722,4 +846,56 @@ typedef FunctionComparison<GreaterOp, NameGreater> FunctionGreater;
|
|||||||
typedef FunctionComparison<LessOrEqualsOp, NameLessOrEquals> FunctionLessOrEquals;
|
typedef FunctionComparison<LessOrEqualsOp, NameLessOrEquals> FunctionLessOrEquals;
|
||||||
typedef FunctionComparison<GreaterOrEqualsOp, NameGreaterOrEquals> FunctionGreaterOrEquals;
|
typedef FunctionComparison<GreaterOrEqualsOp, NameGreaterOrEquals> FunctionGreaterOrEquals;
|
||||||
|
|
||||||
|
|
||||||
|
template <>
|
||||||
|
void FunctionComparison<EqualsOp, NameEquals>::executeTupleImpl(
|
||||||
|
Block & block, size_t result, const ColumnTuple * x, const ColumnTuple * y, size_t tuple_size)
|
||||||
|
{
|
||||||
|
return executeTupleEqualityImpl<FunctionComparison<EqualsOp, NameEquals>, FunctionAnd>(block, result, x, y, tuple_size);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <>
|
||||||
|
void FunctionComparison<NotEqualsOp, NameNotEquals>::executeTupleImpl(
|
||||||
|
Block & block, size_t result, const ColumnTuple * x, const ColumnTuple * y, size_t tuple_size)
|
||||||
|
{
|
||||||
|
return executeTupleEqualityImpl<FunctionComparison<NotEqualsOp, NameNotEquals>, FunctionOr>(block, result, x, y, tuple_size);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <>
|
||||||
|
void FunctionComparison<LessOp, NameLess>::executeTupleImpl(
|
||||||
|
Block & block, size_t result, const ColumnTuple * x, const ColumnTuple * y, size_t tuple_size)
|
||||||
|
{
|
||||||
|
return executeTupleLessGreaterImpl<
|
||||||
|
FunctionComparison<LessOp, NameLess>,
|
||||||
|
FunctionComparison<LessOp, NameLess>>(block, result, x, y, tuple_size);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <>
|
||||||
|
void FunctionComparison<GreaterOp, NameGreater>::executeTupleImpl(
|
||||||
|
Block & block, size_t result, const ColumnTuple * x, const ColumnTuple * y, size_t tuple_size)
|
||||||
|
{
|
||||||
|
return executeTupleLessGreaterImpl<
|
||||||
|
FunctionComparison<GreaterOp, NameGreater>,
|
||||||
|
FunctionComparison<GreaterOp, NameGreater>>(block, result, x, y, tuple_size);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <>
|
||||||
|
void FunctionComparison<LessOrEqualsOp, NameLessOrEquals>::executeTupleImpl(
|
||||||
|
Block & block, size_t result, const ColumnTuple * x, const ColumnTuple * y, size_t tuple_size)
|
||||||
|
{
|
||||||
|
return executeTupleLessGreaterImpl<
|
||||||
|
FunctionComparison<LessOp, NameLess>,
|
||||||
|
FunctionComparison<LessOrEqualsOp, NameLessOrEquals>>(block, result, x, y, tuple_size);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <>
|
||||||
|
void FunctionComparison<GreaterOrEqualsOp, NameGreaterOrEquals>::executeTupleImpl(
|
||||||
|
Block & block, size_t result, const ColumnTuple * x, const ColumnTuple * y, size_t tuple_size)
|
||||||
|
{
|
||||||
|
return executeTupleLessGreaterImpl<
|
||||||
|
FunctionComparison<GreaterOp, NameGreater>,
|
||||||
|
FunctionComparison<GreaterOrEqualsOp, NameGreaterOrEquals>>(block, result, x, y, tuple_size);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -1273,13 +1273,13 @@ private:
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
/// Получить имя функции.
|
/// Получить имя функции.
|
||||||
String getName() const
|
String getName() const override
|
||||||
{
|
{
|
||||||
return name;
|
return name;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Получить типы результата по типам аргументов. Если функция неприменима для данных аргументов - кинуть исключение.
|
/// Получить типы результата по типам аргументов. Если функция неприменима для данных аргументов - кинуть исключение.
|
||||||
DataTypePtr getReturnType(const DataTypes & arguments) const
|
DataTypePtr getReturnType(const DataTypes & arguments) const override
|
||||||
{
|
{
|
||||||
if (arguments.size() != 3)
|
if (arguments.size() != 3)
|
||||||
throw Exception("Number of arguments for function " + getName() + " doesn't match: passed "
|
throw Exception("Number of arguments for function " + getName() + " doesn't match: passed "
|
||||||
@ -1346,7 +1346,7 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Выполнить функцию над блоком.
|
/// Выполнить функцию над блоком.
|
||||||
void execute(Block & block, const ColumnNumbers & arguments, size_t result)
|
void execute(Block & block, const ColumnNumbers & arguments, size_t result) override
|
||||||
{
|
{
|
||||||
const ColumnVector<UInt8> * cond_col = typeid_cast<const ColumnVector<UInt8> *>(&*block.getByPosition(arguments[0]).column);
|
const ColumnVector<UInt8> * cond_col = typeid_cast<const ColumnVector<UInt8> *>(&*block.getByPosition(arguments[0]).column);
|
||||||
const ColumnConst<UInt8> * cond_const_col = typeid_cast<const ColumnConst<UInt8> *>(&*block.getByPosition(arguments[0]).column);
|
const ColumnConst<UInt8> * cond_const_col = typeid_cast<const ColumnConst<UInt8> *>(&*block.getByPosition(arguments[0]).column);
|
||||||
|
@ -896,19 +896,19 @@ public:
|
|||||||
static IFunction * create(const Context & context) { return new FunctionConvert; }
|
static IFunction * create(const Context & context) { return new FunctionConvert; }
|
||||||
|
|
||||||
/// Получить имя функции.
|
/// Получить имя функции.
|
||||||
String getName() const
|
String getName() const override
|
||||||
{
|
{
|
||||||
return name;
|
return name;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Получить тип результата по типам аргументов. Если функция неприменима для данных аргументов - кинуть исключение.
|
/// Получить тип результата по типам аргументов. Если функция неприменима для данных аргументов - кинуть исключение.
|
||||||
DataTypePtr getReturnType(const DataTypes & arguments) const
|
DataTypePtr getReturnType(const DataTypes & arguments) const override
|
||||||
{
|
{
|
||||||
return getReturnTypeImpl(arguments);
|
return getReturnTypeImpl(arguments);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Выполнить функцию над блоком.
|
/// Выполнить функцию над блоком.
|
||||||
void execute(Block & block, const ColumnNumbers & arguments, size_t result)
|
void execute(Block & block, const ColumnNumbers & arguments, size_t result) override
|
||||||
{
|
{
|
||||||
IDataType * from_type = &*block.getByPosition(arguments[0]).type;
|
IDataType * from_type = &*block.getByPosition(arguments[0]).type;
|
||||||
|
|
||||||
@ -1009,7 +1009,7 @@ public:
|
|||||||
static IFunction * create(const Context & context) { return new FunctionToFixedString; };
|
static IFunction * create(const Context & context) { return new FunctionToFixedString; };
|
||||||
|
|
||||||
/// Получить имя функции.
|
/// Получить имя функции.
|
||||||
String getName() const
|
String getName() const override
|
||||||
{
|
{
|
||||||
return name;
|
return name;
|
||||||
}
|
}
|
||||||
@ -1020,7 +1020,7 @@ public:
|
|||||||
*/
|
*/
|
||||||
void getReturnTypeAndPrerequisites(const ColumnsWithTypeAndName & arguments,
|
void getReturnTypeAndPrerequisites(const ColumnsWithTypeAndName & arguments,
|
||||||
DataTypePtr & out_return_type,
|
DataTypePtr & out_return_type,
|
||||||
std::vector<ExpressionAction> & out_prerequisites)
|
std::vector<ExpressionAction> & out_prerequisites) override
|
||||||
{
|
{
|
||||||
if (arguments.size() != 2)
|
if (arguments.size() != 2)
|
||||||
throw Exception("Number of arguments for function " + getName() + " doesn't match: passed "
|
throw Exception("Number of arguments for function " + getName() + " doesn't match: passed "
|
||||||
@ -1038,7 +1038,7 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Выполнить функцию над блоком.
|
/// Выполнить функцию над блоком.
|
||||||
void execute(Block & block, const ColumnNumbers & arguments, size_t result)
|
void execute(Block & block, const ColumnNumbers & arguments, size_t result) override
|
||||||
{
|
{
|
||||||
ColumnPtr column = block.getByPosition(arguments[0]).column;
|
ColumnPtr column = block.getByPosition(arguments[0]).column;
|
||||||
size_t n = getSize(block.getByPosition(arguments[1]));
|
size_t n = getSize(block.getByPosition(arguments[1]));
|
||||||
|
@ -397,7 +397,7 @@ public:
|
|||||||
static IFunction * create(const Context & context) { return new FunctionDateOrDateTimeToSomething; };
|
static IFunction * create(const Context & context) { return new FunctionDateOrDateTimeToSomething; };
|
||||||
|
|
||||||
/// Получить имя функции.
|
/// Получить имя функции.
|
||||||
String getName() const
|
String getName() const override
|
||||||
{
|
{
|
||||||
return name;
|
return name;
|
||||||
}
|
}
|
||||||
@ -408,7 +408,7 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Выполнить функцию над блоком.
|
/// Выполнить функцию над блоком.
|
||||||
void execute(Block & block, const ColumnNumbers & arguments, size_t result)
|
void execute(Block & block, const ColumnNumbers & arguments, size_t result) override
|
||||||
{
|
{
|
||||||
IDataType * from_type = &*block.getByPosition(arguments[0]).type;
|
IDataType * from_type = &*block.getByPosition(arguments[0]).type;
|
||||||
|
|
||||||
@ -479,13 +479,13 @@ public:
|
|||||||
static IFunction * create(const Context & context) { return new FunctionNow; };
|
static IFunction * create(const Context & context) { return new FunctionNow; };
|
||||||
|
|
||||||
/// Получить имя функции.
|
/// Получить имя функции.
|
||||||
String getName() const
|
String getName() const override
|
||||||
{
|
{
|
||||||
return name;
|
return name;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Получить тип результата по типам аргументов. Если функция неприменима для данных аргументов - кинуть исключение.
|
/// Получить тип результата по типам аргументов. Если функция неприменима для данных аргументов - кинуть исключение.
|
||||||
DataTypePtr getReturnType(const DataTypes & arguments) const
|
DataTypePtr getReturnType(const DataTypes & arguments) const override
|
||||||
{
|
{
|
||||||
if (arguments.size() != 0)
|
if (arguments.size() != 0)
|
||||||
throw Exception("Number of arguments for function " + getName() + " doesn't match: passed "
|
throw Exception("Number of arguments for function " + getName() + " doesn't match: passed "
|
||||||
@ -496,7 +496,7 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Выполнить функцию над блоком.
|
/// Выполнить функцию над блоком.
|
||||||
void execute(Block & block, const ColumnNumbers & arguments, size_t result)
|
void execute(Block & block, const ColumnNumbers & arguments, size_t result) override
|
||||||
{
|
{
|
||||||
block.getByPosition(result).column = new ColumnConstUInt32(
|
block.getByPosition(result).column = new ColumnConstUInt32(
|
||||||
block.rowsInFirstColumn(),
|
block.rowsInFirstColumn(),
|
||||||
@ -512,13 +512,13 @@ public:
|
|||||||
static IFunction * create(const Context & context) { return new FunctionToday; };
|
static IFunction * create(const Context & context) { return new FunctionToday; };
|
||||||
|
|
||||||
/// Получить имя функции.
|
/// Получить имя функции.
|
||||||
String getName() const
|
String getName() const override
|
||||||
{
|
{
|
||||||
return name;
|
return name;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Получить тип результата по типам аргументов. Если функция неприменима для данных аргументов - кинуть исключение.
|
/// Получить тип результата по типам аргументов. Если функция неприменима для данных аргументов - кинуть исключение.
|
||||||
DataTypePtr getReturnType(const DataTypes & arguments) const
|
DataTypePtr getReturnType(const DataTypes & arguments) const override
|
||||||
{
|
{
|
||||||
if (arguments.size() != 0)
|
if (arguments.size() != 0)
|
||||||
throw Exception("Number of arguments for function " + getName() + " doesn't match: passed "
|
throw Exception("Number of arguments for function " + getName() + " doesn't match: passed "
|
||||||
@ -529,7 +529,7 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Выполнить функцию над блоком.
|
/// Выполнить функцию над блоком.
|
||||||
void execute(Block & block, const ColumnNumbers & arguments, size_t result)
|
void execute(Block & block, const ColumnNumbers & arguments, size_t result) override
|
||||||
{
|
{
|
||||||
block.getByPosition(result).column = new ColumnConstUInt16(
|
block.getByPosition(result).column = new ColumnConstUInt16(
|
||||||
block.rowsInFirstColumn(),
|
block.rowsInFirstColumn(),
|
||||||
@ -545,13 +545,13 @@ public:
|
|||||||
static IFunction * create(const Context & context) { return new FunctionYesterday; };
|
static IFunction * create(const Context & context) { return new FunctionYesterday; };
|
||||||
|
|
||||||
/// Получить имя функции.
|
/// Получить имя функции.
|
||||||
String getName() const
|
String getName() const override
|
||||||
{
|
{
|
||||||
return name;
|
return name;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Получить тип результата по типам аргументов. Если функция неприменима для данных аргументов - кинуть исключение.
|
/// Получить тип результата по типам аргументов. Если функция неприменима для данных аргументов - кинуть исключение.
|
||||||
DataTypePtr getReturnType(const DataTypes & arguments) const
|
DataTypePtr getReturnType(const DataTypes & arguments) const override
|
||||||
{
|
{
|
||||||
if (arguments.size() != 0)
|
if (arguments.size() != 0)
|
||||||
throw Exception("Number of arguments for function " + getName() + " doesn't match: passed "
|
throw Exception("Number of arguments for function " + getName() + " doesn't match: passed "
|
||||||
@ -562,7 +562,7 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Выполнить функцию над блоком.
|
/// Выполнить функцию над блоком.
|
||||||
void execute(Block & block, const ColumnNumbers & arguments, size_t result)
|
void execute(Block & block, const ColumnNumbers & arguments, size_t result) override
|
||||||
{
|
{
|
||||||
block.getByPosition(result).column = new ColumnConstUInt16(
|
block.getByPosition(result).column = new ColumnConstUInt16(
|
||||||
block.rowsInFirstColumn(),
|
block.rowsInFirstColumn(),
|
||||||
@ -578,13 +578,13 @@ public:
|
|||||||
static IFunction * create(const Context & context) { return new FunctionTimeSlot; };
|
static IFunction * create(const Context & context) { return new FunctionTimeSlot; };
|
||||||
|
|
||||||
/// Получить имя функции.
|
/// Получить имя функции.
|
||||||
String getName() const
|
String getName() const override
|
||||||
{
|
{
|
||||||
return name;
|
return name;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Получить тип результата по типам аргументов. Если функция неприменима для данных аргументов - кинуть исключение.
|
/// Получить тип результата по типам аргументов. Если функция неприменима для данных аргументов - кинуть исключение.
|
||||||
DataTypePtr getReturnType(const DataTypes & arguments) const
|
DataTypePtr getReturnType(const DataTypes & arguments) const override
|
||||||
{
|
{
|
||||||
if (arguments.size() != 1)
|
if (arguments.size() != 1)
|
||||||
throw Exception("Number of arguments for function " + getName() + " doesn't match: passed "
|
throw Exception("Number of arguments for function " + getName() + " doesn't match: passed "
|
||||||
@ -599,7 +599,7 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Выполнить функцию над блоком.
|
/// Выполнить функцию над блоком.
|
||||||
void execute(Block & block, const ColumnNumbers & arguments, size_t result)
|
void execute(Block & block, const ColumnNumbers & arguments, size_t result) override
|
||||||
{
|
{
|
||||||
if (const ColumnUInt32 * times = typeid_cast<const ColumnUInt32 *>(&*block.getByPosition(arguments[0]).column))
|
if (const ColumnUInt32 * times = typeid_cast<const ColumnUInt32 *>(&*block.getByPosition(arguments[0]).column))
|
||||||
{
|
{
|
||||||
@ -714,13 +714,13 @@ public:
|
|||||||
static IFunction * create(const Context & context) { return new FunctionTimeSlots; };
|
static IFunction * create(const Context & context) { return new FunctionTimeSlots; };
|
||||||
|
|
||||||
/// Получить имя функции.
|
/// Получить имя функции.
|
||||||
String getName() const
|
String getName() const override
|
||||||
{
|
{
|
||||||
return name;
|
return name;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Получить тип результата по типам аргументов. Если функция неприменима для данных аргументов - кинуть исключение.
|
/// Получить тип результата по типам аргументов. Если функция неприменима для данных аргументов - кинуть исключение.
|
||||||
DataTypePtr getReturnType(const DataTypes & arguments) const
|
DataTypePtr getReturnType(const DataTypes & arguments) const override
|
||||||
{
|
{
|
||||||
if (arguments.size() != 2)
|
if (arguments.size() != 2)
|
||||||
throw Exception("Number of arguments for function " + getName() + " doesn't match: passed "
|
throw Exception("Number of arguments for function " + getName() + " doesn't match: passed "
|
||||||
@ -739,7 +739,7 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Выполнить функцию над блоком.
|
/// Выполнить функцию над блоком.
|
||||||
void execute(Block & block, const ColumnNumbers & arguments, size_t result)
|
void execute(Block & block, const ColumnNumbers & arguments, size_t result) override
|
||||||
{
|
{
|
||||||
const ColumnUInt32 * starts = typeid_cast<const ColumnUInt32 *>(&*block.getByPosition(arguments[0]).column);
|
const ColumnUInt32 * starts = typeid_cast<const ColumnUInt32 *>(&*block.getByPosition(arguments[0]).column);
|
||||||
const ColumnConstUInt32 * const_starts = typeid_cast<const ColumnConstUInt32 *>(&*block.getByPosition(arguments[0]).column);
|
const ColumnConstUInt32 * const_starts = typeid_cast<const ColumnConstUInt32 *>(&*block.getByPosition(arguments[0]).column);
|
||||||
|
@ -182,13 +182,13 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Получить имя функции.
|
/// Получить имя функции.
|
||||||
String getName() const
|
String getName() const override
|
||||||
{
|
{
|
||||||
return name;
|
return name;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Получить тип результата по типам аргументов. Если функция неприменима для данных аргументов - кинуть исключение.
|
/// Получить тип результата по типам аргументов. Если функция неприменима для данных аргументов - кинуть исключение.
|
||||||
DataTypePtr getReturnType(const DataTypes & arguments) const
|
DataTypePtr getReturnType(const DataTypes & arguments) const override
|
||||||
{
|
{
|
||||||
if (arguments.size() != 1 && arguments.size() != 2)
|
if (arguments.size() != 1 && arguments.size() != 2)
|
||||||
throw Exception("Number of arguments for function " + getName() + " doesn't match: passed "
|
throw Exception("Number of arguments for function " + getName() + " doesn't match: passed "
|
||||||
@ -209,7 +209,7 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Выполнить функцию над блоком.
|
/// Выполнить функцию над блоком.
|
||||||
void execute(Block & block, const ColumnNumbers & arguments, size_t result)
|
void execute(Block & block, const ColumnNumbers & arguments, size_t result) override
|
||||||
{
|
{
|
||||||
/// Ключ словаря, определяющий "точку зрения".
|
/// Ключ словаря, определяющий "точку зрения".
|
||||||
std::string dict_key;
|
std::string dict_key;
|
||||||
@ -274,13 +274,13 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Получить имя функции.
|
/// Получить имя функции.
|
||||||
String getName() const
|
String getName() const override
|
||||||
{
|
{
|
||||||
return name;
|
return name;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Получить тип результата по типам аргументов. Если функция неприменима для данных аргументов - кинуть исключение.
|
/// Получить тип результата по типам аргументов. Если функция неприменима для данных аргументов - кинуть исключение.
|
||||||
DataTypePtr getReturnType(const DataTypes & arguments) const
|
DataTypePtr getReturnType(const DataTypes & arguments) const override
|
||||||
{
|
{
|
||||||
if (arguments.size() != 2 && arguments.size() != 3)
|
if (arguments.size() != 2 && arguments.size() != 3)
|
||||||
throw Exception("Number of arguments for function " + getName() + " doesn't match: passed "
|
throw Exception("Number of arguments for function " + getName() + " doesn't match: passed "
|
||||||
@ -306,7 +306,7 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Выполнить функцию над блоком.
|
/// Выполнить функцию над блоком.
|
||||||
void execute(Block & block, const ColumnNumbers & arguments, size_t result)
|
void execute(Block & block, const ColumnNumbers & arguments, size_t result) override
|
||||||
{
|
{
|
||||||
/// Ключ словаря, определяющий "точку зрения".
|
/// Ключ словаря, определяющий "точку зрения".
|
||||||
std::string dict_key;
|
std::string dict_key;
|
||||||
@ -407,13 +407,13 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Получить имя функции.
|
/// Получить имя функции.
|
||||||
String getName() const
|
String getName() const override
|
||||||
{
|
{
|
||||||
return name;
|
return name;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Получить тип результата по типам аргументов. Если функция неприменима для данных аргументов - кинуть исключение.
|
/// Получить тип результата по типам аргументов. Если функция неприменима для данных аргументов - кинуть исключение.
|
||||||
DataTypePtr getReturnType(const DataTypes & arguments) const
|
DataTypePtr getReturnType(const DataTypes & arguments) const override
|
||||||
{
|
{
|
||||||
if (arguments.size() != 1 && arguments.size() != 2)
|
if (arguments.size() != 1 && arguments.size() != 2)
|
||||||
throw Exception("Number of arguments for function " + getName() + " doesn't match: passed "
|
throw Exception("Number of arguments for function " + getName() + " doesn't match: passed "
|
||||||
@ -434,7 +434,7 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Выполнить функцию над блоком.
|
/// Выполнить функцию над блоком.
|
||||||
void execute(Block & block, const ColumnNumbers & arguments, size_t result)
|
void execute(Block & block, const ColumnNumbers & arguments, size_t result) override
|
||||||
{
|
{
|
||||||
/// Ключ словаря, определяющий "точку зрения".
|
/// Ключ словаря, определяющий "точку зрения".
|
||||||
std::string dict_key;
|
std::string dict_key;
|
||||||
@ -667,13 +667,13 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Получить имя функции.
|
/// Получить имя функции.
|
||||||
String getName() const
|
String getName() const override
|
||||||
{
|
{
|
||||||
return name;
|
return name;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Получить тип результата по типам аргументов. Если функция неприменима для данных аргументов - кинуть исключение.
|
/// Получить тип результата по типам аргументов. Если функция неприменима для данных аргументов - кинуть исключение.
|
||||||
DataTypePtr getReturnType(const DataTypes & arguments) const
|
DataTypePtr getReturnType(const DataTypes & arguments) const override
|
||||||
{
|
{
|
||||||
if (arguments.size() != 1 && arguments.size() != 2)
|
if (arguments.size() != 1 && arguments.size() != 2)
|
||||||
throw Exception("Number of arguments for function " + getName() + " doesn't match: passed "
|
throw Exception("Number of arguments for function " + getName() + " doesn't match: passed "
|
||||||
@ -694,7 +694,7 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Выполнить функцию над блоком.
|
/// Выполнить функцию над блоком.
|
||||||
void execute(Block & block, const ColumnNumbers & arguments, size_t result)
|
void execute(Block & block, const ColumnNumbers & arguments, size_t result) override
|
||||||
{
|
{
|
||||||
RegionsNames::Language language = RegionsNames::Language::RU;
|
RegionsNames::Language language = RegionsNames::Language::RU;
|
||||||
|
|
||||||
|
@ -25,13 +25,13 @@ public:
|
|||||||
static IFunction * create(const Context & context) { return new FunctionBitmaskToList; }
|
static IFunction * create(const Context & context) { return new FunctionBitmaskToList; }
|
||||||
|
|
||||||
/// Получить основное имя функции.
|
/// Получить основное имя функции.
|
||||||
virtual String getName() const
|
virtual String getName() const override
|
||||||
{
|
{
|
||||||
return name;
|
return name;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Получить тип результата по типам аргументов. Если функция неприменима для данных аргументов - кинуть исключение.
|
/// Получить тип результата по типам аргументов. Если функция неприменима для данных аргументов - кинуть исключение.
|
||||||
virtual DataTypePtr getReturnType(const DataTypes & arguments) const
|
virtual DataTypePtr getReturnType(const DataTypes & arguments) const override
|
||||||
{
|
{
|
||||||
if (arguments.size() != 1)
|
if (arguments.size() != 1)
|
||||||
throw Exception("Number of arguments for function " + getName() + " doesn't match: passed "
|
throw Exception("Number of arguments for function " + getName() + " doesn't match: passed "
|
||||||
@ -54,7 +54,7 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Выполнить функцию над блоком.
|
/// Выполнить функцию над блоком.
|
||||||
void execute(Block & block, const ColumnNumbers & arguments, size_t result)
|
void execute(Block & block, const ColumnNumbers & arguments, size_t result) override
|
||||||
{
|
{
|
||||||
if (!( executeType<UInt8>(block, arguments, result)
|
if (!( executeType<UInt8>(block, arguments, result)
|
||||||
|| executeType<UInt16>(block, arguments, result)
|
|| executeType<UInt16>(block, arguments, result)
|
||||||
@ -138,13 +138,13 @@ public:
|
|||||||
static IFunction * create(const Context & context) { return new FunctionFormatReadableSize; }
|
static IFunction * create(const Context & context) { return new FunctionFormatReadableSize; }
|
||||||
|
|
||||||
/// Получить основное имя функции.
|
/// Получить основное имя функции.
|
||||||
virtual String getName() const
|
virtual String getName() const override
|
||||||
{
|
{
|
||||||
return name;
|
return name;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Получить тип результата по типам аргументов. Если функция неприменима для данных аргументов - кинуть исключение.
|
/// Получить тип результата по типам аргументов. Если функция неприменима для данных аргументов - кинуть исключение.
|
||||||
virtual DataTypePtr getReturnType(const DataTypes & arguments) const
|
virtual DataTypePtr getReturnType(const DataTypes & arguments) const override
|
||||||
{
|
{
|
||||||
if (arguments.size() != 1)
|
if (arguments.size() != 1)
|
||||||
throw Exception("Number of arguments for function " + getName() + " doesn't match: passed "
|
throw Exception("Number of arguments for function " + getName() + " doesn't match: passed "
|
||||||
@ -160,7 +160,7 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Выполнить функцию над блоком.
|
/// Выполнить функцию над блоком.
|
||||||
void execute(Block & block, const ColumnNumbers & arguments, size_t result)
|
void execute(Block & block, const ColumnNumbers & arguments, size_t result) override
|
||||||
{
|
{
|
||||||
if (!( executeType<UInt8>(block, arguments, result)
|
if (!( executeType<UInt8>(block, arguments, result)
|
||||||
|| executeType<UInt16>(block, arguments, result)
|
|| executeType<UInt16>(block, arguments, result)
|
||||||
|
@ -174,13 +174,13 @@ public:
|
|||||||
static IFunction * create(const Context & context) { return new FunctionStringHash64; };
|
static IFunction * create(const Context & context) { return new FunctionStringHash64; };
|
||||||
|
|
||||||
/// Получить имя функции.
|
/// Получить имя функции.
|
||||||
String getName() const
|
String getName() const override
|
||||||
{
|
{
|
||||||
return name;
|
return name;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Получить тип результата по типам аргументов. Если функция неприменима для данных аргументов - кинуть исключение.
|
/// Получить тип результата по типам аргументов. Если функция неприменима для данных аргументов - кинуть исключение.
|
||||||
DataTypePtr getReturnType(const DataTypes & arguments) const
|
DataTypePtr getReturnType(const DataTypes & arguments) const override
|
||||||
{
|
{
|
||||||
if (arguments.size() != 1)
|
if (arguments.size() != 1)
|
||||||
throw Exception("Number of arguments for function " + getName() + " doesn't match: passed "
|
throw Exception("Number of arguments for function " + getName() + " doesn't match: passed "
|
||||||
@ -195,7 +195,7 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Выполнить функцию над блоком.
|
/// Выполнить функцию над блоком.
|
||||||
void execute(Block & block, const ColumnNumbers & arguments, size_t result)
|
void execute(Block & block, const ColumnNumbers & arguments, size_t result) override
|
||||||
{
|
{
|
||||||
if (const ColumnString * col_from = typeid_cast<const ColumnString *>(&*block.getByPosition(arguments[0]).column))
|
if (const ColumnString * col_from = typeid_cast<const ColumnString *>(&*block.getByPosition(arguments[0]).column))
|
||||||
{
|
{
|
||||||
@ -235,13 +235,13 @@ public:
|
|||||||
static IFunction * create(const Context & context) { return new FunctionStringHashFixedString; };
|
static IFunction * create(const Context & context) { return new FunctionStringHashFixedString; };
|
||||||
|
|
||||||
/// Получить имя функции.
|
/// Получить имя функции.
|
||||||
String getName() const
|
String getName() const override
|
||||||
{
|
{
|
||||||
return name;
|
return name;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Получить тип результата по типам аргументов. Если функция неприменима для данных аргументов - кинуть исключение.
|
/// Получить тип результата по типам аргументов. Если функция неприменима для данных аргументов - кинуть исключение.
|
||||||
DataTypePtr getReturnType(const DataTypes & arguments) const
|
DataTypePtr getReturnType(const DataTypes & arguments) const override
|
||||||
{
|
{
|
||||||
if (arguments.size() != 1)
|
if (arguments.size() != 1)
|
||||||
throw Exception("Number of arguments for function " + getName() + " doesn't match: passed "
|
throw Exception("Number of arguments for function " + getName() + " doesn't match: passed "
|
||||||
@ -256,7 +256,7 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Выполнить функцию над блоком.
|
/// Выполнить функцию над блоком.
|
||||||
void execute(Block & block, const ColumnNumbers & arguments, size_t result)
|
void execute(Block & block, const ColumnNumbers & arguments, size_t result) override
|
||||||
{
|
{
|
||||||
if (const ColumnString * col_from = typeid_cast<const ColumnString *>(&*block.getByPosition(arguments[0]).column))
|
if (const ColumnString * col_from = typeid_cast<const ColumnString *>(&*block.getByPosition(arguments[0]).column))
|
||||||
{
|
{
|
||||||
@ -334,13 +334,13 @@ private:
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
/// Получить имя функции.
|
/// Получить имя функции.
|
||||||
String getName() const
|
String getName() const override
|
||||||
{
|
{
|
||||||
return name;
|
return name;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Получить тип результата по типам аргументов. Если функция неприменима для данных аргументов - кинуть исключение.
|
/// Получить тип результата по типам аргументов. Если функция неприменима для данных аргументов - кинуть исключение.
|
||||||
DataTypePtr getReturnType(const DataTypes & arguments) const
|
DataTypePtr getReturnType(const DataTypes & arguments) const override
|
||||||
{
|
{
|
||||||
if (arguments.size() != 1)
|
if (arguments.size() != 1)
|
||||||
throw Exception("Number of arguments for function " + getName() + " doesn't match: passed "
|
throw Exception("Number of arguments for function " + getName() + " doesn't match: passed "
|
||||||
@ -355,7 +355,7 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Выполнить функцию над блоком.
|
/// Выполнить функцию над блоком.
|
||||||
void execute(Block & block, const ColumnNumbers & arguments, size_t result)
|
void execute(Block & block, const ColumnNumbers & arguments, size_t result) override
|
||||||
{
|
{
|
||||||
IDataType * from_type = &*block.getByPosition(arguments[0]).type;
|
IDataType * from_type = &*block.getByPosition(arguments[0]).type;
|
||||||
|
|
||||||
@ -567,19 +567,19 @@ private:
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
/// Получить имя функции.
|
/// Получить имя функции.
|
||||||
String getName() const
|
String getName() const override
|
||||||
{
|
{
|
||||||
return name;
|
return name;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Получить тип результата по типам аргументов. Если функция неприменима для данных аргументов - кинуть исключение.
|
/// Получить тип результата по типам аргументов. Если функция неприменима для данных аргументов - кинуть исключение.
|
||||||
DataTypePtr getReturnType(const DataTypes & arguments) const
|
DataTypePtr getReturnType(const DataTypes & arguments) const override
|
||||||
{
|
{
|
||||||
return new DataTypeUInt64;
|
return new DataTypeUInt64;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Выполнить функцию над блоком.
|
/// Выполнить функцию над блоком.
|
||||||
void execute(Block & block, const ColumnNumbers & arguments, size_t result)
|
void execute(Block & block, const ColumnNumbers & arguments, size_t result) override
|
||||||
{
|
{
|
||||||
size_t rows = block.rowsInFirstColumn();
|
size_t rows = block.rowsInFirstColumn();
|
||||||
ColumnUInt64 * col_to = new ColumnUInt64(rows);
|
ColumnUInt64 * col_to = new ColumnUInt64(rows);
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
#include <DB/Columns/ColumnExpression.h>
|
#include <DB/Columns/ColumnExpression.h>
|
||||||
|
|
||||||
#include <DB/Functions/IFunction.h>
|
#include <DB/Functions/IFunction.h>
|
||||||
#include "FunctionsMiscellaneous.h"
|
#include <DB/Functions/FunctionsMiscellaneous.h>
|
||||||
|
|
||||||
|
|
||||||
namespace DB
|
namespace DB
|
||||||
@ -549,7 +549,7 @@ public:
|
|||||||
static IFunction * create(const Context & context) { return new FunctionArrayMapped; };
|
static IFunction * create(const Context & context) { return new FunctionArrayMapped; };
|
||||||
|
|
||||||
/// Получить имя функции.
|
/// Получить имя функции.
|
||||||
String getName() const
|
String getName() const override
|
||||||
{
|
{
|
||||||
return name;
|
return name;
|
||||||
}
|
}
|
||||||
@ -588,7 +588,7 @@ public:
|
|||||||
|
|
||||||
void getReturnTypeAndPrerequisites(const ColumnsWithTypeAndName & arguments,
|
void getReturnTypeAndPrerequisites(const ColumnsWithTypeAndName & arguments,
|
||||||
DataTypePtr & out_return_type,
|
DataTypePtr & out_return_type,
|
||||||
ExpressionActions::Actions & out_prerequisites)
|
ExpressionActions::Actions & out_prerequisites) override
|
||||||
{
|
{
|
||||||
size_t min_args = Impl::needExpression() ? 2 : 1;
|
size_t min_args = Impl::needExpression() ? 2 : 1;
|
||||||
if (arguments.size() < min_args)
|
if (arguments.size() < min_args)
|
||||||
|
@ -242,13 +242,13 @@ private:
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
/// Получить имя функции.
|
/// Получить имя функции.
|
||||||
String getName() const
|
String getName() const override
|
||||||
{
|
{
|
||||||
return name;
|
return name;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Получить типы результата по типам аргументов. Если функция неприменима для данных аргументов - кинуть исключение.
|
/// Получить типы результата по типам аргументов. Если функция неприменима для данных аргументов - кинуть исключение.
|
||||||
DataTypePtr getReturnType(const DataTypes & arguments) const
|
DataTypePtr getReturnType(const DataTypes & arguments) const override
|
||||||
{
|
{
|
||||||
if (arguments.size() < 2)
|
if (arguments.size() < 2)
|
||||||
throw Exception("Number of arguments for function " + getName() + " doesn't match: passed "
|
throw Exception("Number of arguments for function " + getName() + " doesn't match: passed "
|
||||||
@ -268,7 +268,7 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Выполнить функцию над блоком.
|
/// Выполнить функцию над блоком.
|
||||||
void execute(Block & block, const ColumnNumbers & arguments, size_t result)
|
void execute(Block & block, const ColumnNumbers & arguments, size_t result) override
|
||||||
{
|
{
|
||||||
ColumnPlainPtrs in(arguments.size());
|
ColumnPlainPtrs in(arguments.size());
|
||||||
for (size_t i = 0; i < arguments.size(); ++i)
|
for (size_t i = 0; i < arguments.size(); ++i)
|
||||||
@ -396,13 +396,13 @@ private:
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
/// Получить имя функции.
|
/// Получить имя функции.
|
||||||
String getName() const
|
String getName() const override
|
||||||
{
|
{
|
||||||
return name;
|
return name;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Получить типы результата по типам аргументов. Если функция неприменима для данных аргументов - кинуть исключение.
|
/// Получить типы результата по типам аргументов. Если функция неприменима для данных аргументов - кинуть исключение.
|
||||||
DataTypePtr getReturnType(const DataTypes & arguments) const
|
DataTypePtr getReturnType(const DataTypes & arguments) const override
|
||||||
{
|
{
|
||||||
if (arguments.size() != 1)
|
if (arguments.size() != 1)
|
||||||
throw Exception("Number of arguments for function " + getName() + " doesn't match: passed "
|
throw Exception("Number of arguments for function " + getName() + " doesn't match: passed "
|
||||||
@ -419,7 +419,7 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Выполнить функцию над блоком.
|
/// Выполнить функцию над блоком.
|
||||||
void execute(Block & block, const ColumnNumbers & arguments, size_t result)
|
void execute(Block & block, const ColumnNumbers & arguments, size_t result) override
|
||||||
{
|
{
|
||||||
if (!( executeType<UInt8>(block, arguments, result)
|
if (!( executeType<UInt8>(block, arguments, result)
|
||||||
|| executeType<UInt16>(block, arguments, result)
|
|| executeType<UInt16>(block, arguments, result)
|
||||||
|
@ -4,6 +4,7 @@
|
|||||||
#include <common/Revision.h>
|
#include <common/Revision.h>
|
||||||
|
|
||||||
#include <DB/Core/Defines.h>
|
#include <DB/Core/Defines.h>
|
||||||
|
#include <DB/Core/FieldVisitors.h>
|
||||||
#include <DB/IO/WriteBufferFromString.h>
|
#include <DB/IO/WriteBufferFromString.h>
|
||||||
#include <DB/DataTypes/DataTypesNumberFixed.h>
|
#include <DB/DataTypes/DataTypesNumberFixed.h>
|
||||||
#include <DB/DataTypes/DataTypeString.h>
|
#include <DB/DataTypes/DataTypeString.h>
|
||||||
@ -94,11 +95,11 @@ public:
|
|||||||
|
|
||||||
explicit FunctionCurrentDatabase(const String & db_name) : db_name{db_name} {}
|
explicit FunctionCurrentDatabase(const String & db_name) : db_name{db_name} {}
|
||||||
|
|
||||||
String getName() const {
|
String getName() const override {
|
||||||
return name;
|
return name;
|
||||||
}
|
}
|
||||||
|
|
||||||
DataTypePtr getReturnType(const DataTypes & arguments) const
|
DataTypePtr getReturnType(const DataTypes & arguments) const override
|
||||||
{
|
{
|
||||||
if (arguments.size() != 0)
|
if (arguments.size() != 0)
|
||||||
throw Exception("Number of arguments for function " + getName() + " doesn't match: passed "
|
throw Exception("Number of arguments for function " + getName() + " doesn't match: passed "
|
||||||
@ -125,13 +126,13 @@ public:
|
|||||||
static IFunction * create(const Context & context) { return new FunctionHostName; }
|
static IFunction * create(const Context & context) { return new FunctionHostName; }
|
||||||
|
|
||||||
/// Получить имя функции.
|
/// Получить имя функции.
|
||||||
String getName() const
|
String getName() const override
|
||||||
{
|
{
|
||||||
return name;
|
return name;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Получить тип результата по типам аргументов. Если функция неприменима для данных аргументов - кинуть исключение.
|
/// Получить тип результата по типам аргументов. Если функция неприменима для данных аргументов - кинуть исключение.
|
||||||
DataTypePtr getReturnType(const DataTypes & arguments) const
|
DataTypePtr getReturnType(const DataTypes & arguments) const override
|
||||||
{
|
{
|
||||||
if (arguments.size() != 0)
|
if (arguments.size() != 0)
|
||||||
throw Exception("Number of arguments for function " + getName() + " doesn't match: passed "
|
throw Exception("Number of arguments for function " + getName() + " doesn't match: passed "
|
||||||
@ -143,7 +144,7 @@ public:
|
|||||||
|
|
||||||
/** Выполнить функцию над блоком. convertToFullColumn вызывается для того, чтобы в случае
|
/** Выполнить функцию над блоком. convertToFullColumn вызывается для того, чтобы в случае
|
||||||
* распределенного выполнения запроса каждый сервер возвращал свое имя хоста. */
|
* распределенного выполнения запроса каждый сервер возвращал свое имя хоста. */
|
||||||
void execute(Block & block, const ColumnNumbers & arguments, size_t result)
|
void execute(Block & block, const ColumnNumbers & arguments, size_t result) override
|
||||||
{
|
{
|
||||||
block.getByPosition(result).column = ColumnConstString(
|
block.getByPosition(result).column = ColumnConstString(
|
||||||
block.rowsInFirstColumn(),
|
block.rowsInFirstColumn(),
|
||||||
@ -159,13 +160,13 @@ public:
|
|||||||
static IFunction * create(const Context & context) { return new FunctionVisibleWidth; }
|
static IFunction * create(const Context & context) { return new FunctionVisibleWidth; }
|
||||||
|
|
||||||
/// Получить имя функции.
|
/// Получить имя функции.
|
||||||
String getName() const
|
String getName() const override
|
||||||
{
|
{
|
||||||
return name;
|
return name;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Получить тип результата по типам аргументов. Если функция неприменима для данных аргументов - кинуть исключение.
|
/// Получить тип результата по типам аргументов. Если функция неприменима для данных аргументов - кинуть исключение.
|
||||||
DataTypePtr getReturnType(const DataTypes & arguments) const
|
DataTypePtr getReturnType(const DataTypes & arguments) const override
|
||||||
{
|
{
|
||||||
if (arguments.size() != 1)
|
if (arguments.size() != 1)
|
||||||
throw Exception("Number of arguments for function " + getName() + " doesn't match: passed "
|
throw Exception("Number of arguments for function " + getName() + " doesn't match: passed "
|
||||||
@ -176,7 +177,7 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Выполнить функцию над блоком.
|
/// Выполнить функцию над блоком.
|
||||||
void execute(Block & block, const ColumnNumbers & arguments, size_t result);
|
void execute(Block & block, const ColumnNumbers & arguments, size_t result) override;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@ -187,13 +188,13 @@ public:
|
|||||||
static IFunction * create(const Context & context) { return new FunctionToTypeName; }
|
static IFunction * create(const Context & context) { return new FunctionToTypeName; }
|
||||||
|
|
||||||
/// Получить имя функции.
|
/// Получить имя функции.
|
||||||
String getName() const
|
String getName() const override
|
||||||
{
|
{
|
||||||
return name;
|
return name;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Получить тип результата по типам аргументов. Если функция неприменима для данных аргументов - кинуть исключение.
|
/// Получить тип результата по типам аргументов. Если функция неприменима для данных аргументов - кинуть исключение.
|
||||||
DataTypePtr getReturnType(const DataTypes & arguments) const
|
DataTypePtr getReturnType(const DataTypes & arguments) const override
|
||||||
{
|
{
|
||||||
if (arguments.size() != 1)
|
if (arguments.size() != 1)
|
||||||
throw Exception("Number of arguments for function " + getName() + " doesn't match: passed "
|
throw Exception("Number of arguments for function " + getName() + " doesn't match: passed "
|
||||||
@ -204,7 +205,7 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Выполнить функцию над блоком.
|
/// Выполнить функцию над блоком.
|
||||||
void execute(Block & block, const ColumnNumbers & arguments, size_t result)
|
void execute(Block & block, const ColumnNumbers & arguments, size_t result) override
|
||||||
{
|
{
|
||||||
block.getByPosition(result).column = new ColumnConstString(block.rowsInFirstColumn(), block.getByPosition(arguments[0]).type->getName());
|
block.getByPosition(result).column = new ColumnConstString(block.rowsInFirstColumn(), block.getByPosition(arguments[0]).type->getName());
|
||||||
}
|
}
|
||||||
@ -218,13 +219,13 @@ public:
|
|||||||
static IFunction * create(const Context & context) { return new FunctionBlockSize; }
|
static IFunction * create(const Context & context) { return new FunctionBlockSize; }
|
||||||
|
|
||||||
/// Получить имя функции.
|
/// Получить имя функции.
|
||||||
String getName() const
|
String getName() const override
|
||||||
{
|
{
|
||||||
return name;
|
return name;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Получить тип результата по типам аргументов. Если функция неприменима для данных аргументов - кинуть исключение.
|
/// Получить тип результата по типам аргументов. Если функция неприменима для данных аргументов - кинуть исключение.
|
||||||
DataTypePtr getReturnType(const DataTypes & arguments) const
|
DataTypePtr getReturnType(const DataTypes & arguments) const override
|
||||||
{
|
{
|
||||||
if (!arguments.empty())
|
if (!arguments.empty())
|
||||||
throw Exception("Number of arguments for function " + getName() + " doesn't match: passed "
|
throw Exception("Number of arguments for function " + getName() + " doesn't match: passed "
|
||||||
@ -235,7 +236,7 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Выполнить функцию над блоком.
|
/// Выполнить функцию над блоком.
|
||||||
void execute(Block & block, const ColumnNumbers & arguments, size_t result)
|
void execute(Block & block, const ColumnNumbers & arguments, size_t result) override
|
||||||
{
|
{
|
||||||
size_t size = block.rowsInFirstColumn();
|
size_t size = block.rowsInFirstColumn();
|
||||||
block.getByPosition(result).column = ColumnConstUInt64(size, size).convertToFullColumn();
|
block.getByPosition(result).column = ColumnConstUInt64(size, size).convertToFullColumn();
|
||||||
@ -250,13 +251,13 @@ public:
|
|||||||
static IFunction * create(const Context & context) { return new FunctionSleep; }
|
static IFunction * create(const Context & context) { return new FunctionSleep; }
|
||||||
|
|
||||||
/// Получить имя функции.
|
/// Получить имя функции.
|
||||||
String getName() const
|
String getName() const override
|
||||||
{
|
{
|
||||||
return name;
|
return name;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Получить тип результата по типам аргументов. Если функция неприменима для данных аргументов - кинуть исключение.
|
/// Получить тип результата по типам аргументов. Если функция неприменима для данных аргументов - кинуть исключение.
|
||||||
DataTypePtr getReturnType(const DataTypes & arguments) const
|
DataTypePtr getReturnType(const DataTypes & arguments) const override
|
||||||
{
|
{
|
||||||
if (arguments.size() != 1)
|
if (arguments.size() != 1)
|
||||||
throw Exception("Number of arguments for function " + getName() + " doesn't match: passed "
|
throw Exception("Number of arguments for function " + getName() + " doesn't match: passed "
|
||||||
@ -276,7 +277,7 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Выполнить функцию над блоком.
|
/// Выполнить функцию над блоком.
|
||||||
void execute(Block & block, const ColumnNumbers & arguments, size_t result)
|
void execute(Block & block, const ColumnNumbers & arguments, size_t result) override
|
||||||
{
|
{
|
||||||
IColumn * col = &*block.getByPosition(arguments[0]).column;
|
IColumn * col = &*block.getByPosition(arguments[0]).column;
|
||||||
double seconds;
|
double seconds;
|
||||||
@ -319,13 +320,13 @@ public:
|
|||||||
static IFunction * create(const Context & context) { return new FunctionMaterialize; }
|
static IFunction * create(const Context & context) { return new FunctionMaterialize; }
|
||||||
|
|
||||||
/// Получить имя функции.
|
/// Получить имя функции.
|
||||||
String getName() const
|
String getName() const override
|
||||||
{
|
{
|
||||||
return name;
|
return name;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Получить тип результата по типам аргументов. Если функция неприменима для данных аргументов - кинуть исключение.
|
/// Получить тип результата по типам аргументов. Если функция неприменима для данных аргументов - кинуть исключение.
|
||||||
DataTypePtr getReturnType(const DataTypes & arguments) const
|
DataTypePtr getReturnType(const DataTypes & arguments) const override
|
||||||
{
|
{
|
||||||
if (arguments.size() != 1)
|
if (arguments.size() != 1)
|
||||||
throw Exception("Number of arguments for function " + getName() + " doesn't match: passed "
|
throw Exception("Number of arguments for function " + getName() + " doesn't match: passed "
|
||||||
@ -336,7 +337,7 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Выполнить функцию над блоком.
|
/// Выполнить функцию над блоком.
|
||||||
void execute(Block & block, const ColumnNumbers & arguments, size_t result)
|
void execute(Block & block, const ColumnNumbers & arguments, size_t result) override
|
||||||
{
|
{
|
||||||
const IColumn & argument = *block.getByPosition(arguments[0]).column;
|
const IColumn & argument = *block.getByPosition(arguments[0]).column;
|
||||||
if (!argument.isConst())
|
if (!argument.isConst())
|
||||||
@ -360,13 +361,13 @@ public:
|
|||||||
static IFunction * create(const Context & context) { return new FunctionIn; }
|
static IFunction * create(const Context & context) { return new FunctionIn; }
|
||||||
|
|
||||||
/// Получить имя функции.
|
/// Получить имя функции.
|
||||||
String getName() const
|
String getName() const override
|
||||||
{
|
{
|
||||||
return name;
|
return name;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Получить тип результата по типам аргументов. Если функция неприменима для данных аргументов - кинуть исключение.
|
/// Получить тип результата по типам аргументов. Если функция неприменима для данных аргументов - кинуть исключение.
|
||||||
DataTypePtr getReturnType(const DataTypes & arguments) const
|
DataTypePtr getReturnType(const DataTypes & arguments) const override
|
||||||
{
|
{
|
||||||
if (arguments.size() != 2)
|
if (arguments.size() != 2)
|
||||||
throw Exception("Number of arguments for function '" + getName() + "' doesn't match: passed "
|
throw Exception("Number of arguments for function '" + getName() + "' doesn't match: passed "
|
||||||
@ -377,7 +378,7 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Выполнить функцию над блоком.
|
/// Выполнить функцию над блоком.
|
||||||
void execute(Block & block, const ColumnNumbers & arguments, size_t result)
|
void execute(Block & block, const ColumnNumbers & arguments, size_t result) override
|
||||||
{
|
{
|
||||||
/// Второй аргумент - обязательно ColumnSet.
|
/// Второй аргумент - обязательно ColumnSet.
|
||||||
ColumnPtr column_set_ptr = block.getByPosition(arguments[1]).column;
|
ColumnPtr column_set_ptr = block.getByPosition(arguments[1]).column;
|
||||||
@ -407,13 +408,13 @@ public:
|
|||||||
static IFunction * create(const Context & context) { return new FunctionTuple; }
|
static IFunction * create(const Context & context) { return new FunctionTuple; }
|
||||||
|
|
||||||
/// Получить имя функции.
|
/// Получить имя функции.
|
||||||
String getName() const
|
String getName() const override
|
||||||
{
|
{
|
||||||
return name;
|
return name;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Получить тип результата по типам аргументов. Если функция неприменима для данных аргументов - кинуть исключение.
|
/// Получить тип результата по типам аргументов. Если функция неприменима для данных аргументов - кинуть исключение.
|
||||||
DataTypePtr getReturnType(const DataTypes & arguments) const
|
DataTypePtr getReturnType(const DataTypes & arguments) const override
|
||||||
{
|
{
|
||||||
if (arguments.size() < 1)
|
if (arguments.size() < 1)
|
||||||
throw Exception("Function " + getName() + " requires at least one argument.", ErrorCodes::NUMBER_OF_ARGUMENTS_DOESNT_MATCH);
|
throw Exception("Function " + getName() + " requires at least one argument.", ErrorCodes::NUMBER_OF_ARGUMENTS_DOESNT_MATCH);
|
||||||
@ -422,7 +423,7 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Выполнить функцию над блоком.
|
/// Выполнить функцию над блоком.
|
||||||
void execute(Block & block, const ColumnNumbers & arguments, size_t result)
|
void execute(Block & block, const ColumnNumbers & arguments, size_t result) override
|
||||||
{
|
{
|
||||||
Block tuple_block;
|
Block tuple_block;
|
||||||
|
|
||||||
@ -441,14 +442,14 @@ public:
|
|||||||
static IFunction * create(const Context & context) { return new FunctionTupleElement; }
|
static IFunction * create(const Context & context) { return new FunctionTupleElement; }
|
||||||
|
|
||||||
/// Получить имя функции.
|
/// Получить имя функции.
|
||||||
String getName() const
|
String getName() const override
|
||||||
{
|
{
|
||||||
return name;
|
return name;
|
||||||
}
|
}
|
||||||
|
|
||||||
void getReturnTypeAndPrerequisites(const ColumnsWithTypeAndName & arguments,
|
void getReturnTypeAndPrerequisites(const ColumnsWithTypeAndName & arguments,
|
||||||
DataTypePtr & out_return_type,
|
DataTypePtr & out_return_type,
|
||||||
ExpressionActions::Actions & out_prerequisites)
|
ExpressionActions::Actions & out_prerequisites) override
|
||||||
{
|
{
|
||||||
if (arguments.size() != 2)
|
if (arguments.size() != 2)
|
||||||
throw Exception("Function " + getName() + " requires exactly two arguments: tuple and element index.",
|
throw Exception("Function " + getName() + " requires exactly two arguments: tuple and element index.",
|
||||||
@ -476,7 +477,7 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Выполнить функцию над блоком.
|
/// Выполнить функцию над блоком.
|
||||||
void execute(Block & block, const ColumnNumbers & arguments, size_t result)
|
void execute(Block & block, const ColumnNumbers & arguments, size_t result) override
|
||||||
{
|
{
|
||||||
const ColumnTuple * tuple_col = typeid_cast<const ColumnTuple *>(&*block.getByPosition(arguments[0]).column);
|
const ColumnTuple * tuple_col = typeid_cast<const ColumnTuple *>(&*block.getByPosition(arguments[0]).column);
|
||||||
const ColumnConstUInt8 * index_col = typeid_cast<const ColumnConstUInt8 *>(&*block.getByPosition(arguments[1]).column);
|
const ColumnConstUInt8 * index_col = typeid_cast<const ColumnConstUInt8 *>(&*block.getByPosition(arguments[1]).column);
|
||||||
@ -508,19 +509,19 @@ public:
|
|||||||
static IFunction * create(const Context & context) { return new FunctionIgnore; }
|
static IFunction * create(const Context & context) { return new FunctionIgnore; }
|
||||||
|
|
||||||
/// Получить имя функции.
|
/// Получить имя функции.
|
||||||
String getName() const
|
String getName() const override
|
||||||
{
|
{
|
||||||
return name;
|
return name;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Получить тип результата по типам аргументов. Если функция неприменима для данных аргументов - кинуть исключение.
|
/// Получить тип результата по типам аргументов. Если функция неприменима для данных аргументов - кинуть исключение.
|
||||||
DataTypePtr getReturnType(const DataTypes & arguments) const
|
DataTypePtr getReturnType(const DataTypes & arguments) const override
|
||||||
{
|
{
|
||||||
return new DataTypeUInt8;
|
return new DataTypeUInt8;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Выполнить функцию над блоком.
|
/// Выполнить функцию над блоком.
|
||||||
void execute(Block & block, const ColumnNumbers & arguments, size_t result)
|
void execute(Block & block, const ColumnNumbers & arguments, size_t result) override
|
||||||
{
|
{
|
||||||
block.getByPosition(result).column = new ColumnConstUInt8(block.rowsInFirstColumn(), 0);
|
block.getByPosition(result).column = new ColumnConstUInt8(block.rowsInFirstColumn(), 0);
|
||||||
}
|
}
|
||||||
@ -534,13 +535,13 @@ public:
|
|||||||
static IFunction * create(const Context & context) { return new FunctionIdentity; }
|
static IFunction * create(const Context & context) { return new FunctionIdentity; }
|
||||||
|
|
||||||
/// Получить имя функции.
|
/// Получить имя функции.
|
||||||
String getName() const
|
String getName() const override
|
||||||
{
|
{
|
||||||
return name;
|
return name;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Получить тип результата по типам аргументов. Если функция неприменима для данных аргументов - кинуть исключение.
|
/// Получить тип результата по типам аргументов. Если функция неприменима для данных аргументов - кинуть исключение.
|
||||||
DataTypePtr getReturnType(const DataTypes & arguments) const
|
DataTypePtr getReturnType(const DataTypes & arguments) const override
|
||||||
{
|
{
|
||||||
if (arguments.size() != 1)
|
if (arguments.size() != 1)
|
||||||
throw Exception("Function " + getName() + " requires exactly one argument.",
|
throw Exception("Function " + getName() + " requires exactly one argument.",
|
||||||
@ -550,7 +551,7 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Выполнить функцию над блоком.
|
/// Выполнить функцию над блоком.
|
||||||
void execute(Block & block, const ColumnNumbers & arguments, size_t result)
|
void execute(Block & block, const ColumnNumbers & arguments, size_t result) override
|
||||||
{
|
{
|
||||||
block.getByPosition(result).column = block.getByPosition(arguments.front()).column;
|
block.getByPosition(result).column = block.getByPosition(arguments.front()).column;
|
||||||
}
|
}
|
||||||
@ -565,13 +566,13 @@ public:
|
|||||||
|
|
||||||
|
|
||||||
/// Получить имя функции.
|
/// Получить имя функции.
|
||||||
String getName() const
|
String getName() const override
|
||||||
{
|
{
|
||||||
return name;
|
return name;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Получить тип результата по типам аргументов. Если функция неприменима для данных аргументов - кинуть исключение.
|
/// Получить тип результата по типам аргументов. Если функция неприменима для данных аргументов - кинуть исключение.
|
||||||
DataTypePtr getReturnType(const DataTypes & arguments) const
|
DataTypePtr getReturnType(const DataTypes & arguments) const override
|
||||||
{
|
{
|
||||||
if (arguments.size() != 1)
|
if (arguments.size() != 1)
|
||||||
throw Exception("Function " + getName() + " requires exactly one argument.", ErrorCodes::NUMBER_OF_ARGUMENTS_DOESNT_MATCH);
|
throw Exception("Function " + getName() + " requires exactly one argument.", ErrorCodes::NUMBER_OF_ARGUMENTS_DOESNT_MATCH);
|
||||||
@ -584,7 +585,7 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Выполнить функцию над блоком.
|
/// Выполнить функцию над блоком.
|
||||||
void execute(Block & block, const ColumnNumbers & arguments, size_t result)
|
void execute(Block & block, const ColumnNumbers & arguments, size_t result) override
|
||||||
{
|
{
|
||||||
throw Exception("Function " + getName() + " must not be executed directly.", ErrorCodes::FUNCTION_IS_SPECIAL);
|
throw Exception("Function " + getName() + " must not be executed directly.", ErrorCodes::FUNCTION_IS_SPECIAL);
|
||||||
}
|
}
|
||||||
@ -601,13 +602,13 @@ public:
|
|||||||
static IFunction * create(const Context & context) { return new FunctionReplicate; }
|
static IFunction * create(const Context & context) { return new FunctionReplicate; }
|
||||||
|
|
||||||
/// Получить имя функции.
|
/// Получить имя функции.
|
||||||
String getName() const
|
String getName() const override
|
||||||
{
|
{
|
||||||
return name;
|
return name;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Получить типы результата по типам аргументов. Если функция неприменима для данных аргументов - кинуть исключение.
|
/// Получить типы результата по типам аргументов. Если функция неприменима для данных аргументов - кинуть исключение.
|
||||||
DataTypePtr getReturnType(const DataTypes & arguments) const
|
DataTypePtr getReturnType(const DataTypes & arguments) const override
|
||||||
{
|
{
|
||||||
if (arguments.size() != 2)
|
if (arguments.size() != 2)
|
||||||
throw Exception("Number of arguments for function " + getName() + " doesn't match: passed "
|
throw Exception("Number of arguments for function " + getName() + " doesn't match: passed "
|
||||||
@ -622,7 +623,7 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Выполнить функцию над блоком.
|
/// Выполнить функцию над блоком.
|
||||||
void execute(Block & block, const ColumnNumbers & arguments, size_t result)
|
void execute(Block & block, const ColumnNumbers & arguments, size_t result) override
|
||||||
{
|
{
|
||||||
ColumnPtr first_column = block.getByPosition(arguments[0]).column;
|
ColumnPtr first_column = block.getByPosition(arguments[0]).column;
|
||||||
|
|
||||||
@ -652,13 +653,13 @@ public:
|
|||||||
static IFunction * create(const Context & context) { return new FunctionBar; }
|
static IFunction * create(const Context & context) { return new FunctionBar; }
|
||||||
|
|
||||||
/// Получить имя функции.
|
/// Получить имя функции.
|
||||||
String getName() const
|
String getName() const override
|
||||||
{
|
{
|
||||||
return name;
|
return name;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Получить тип результата по типам аргументов. Если функция неприменима для данных аргументов - кинуть исключение.
|
/// Получить тип результата по типам аргументов. Если функция неприменима для данных аргументов - кинуть исключение.
|
||||||
DataTypePtr getReturnType(const DataTypes & arguments) const
|
DataTypePtr getReturnType(const DataTypes & arguments) const override
|
||||||
{
|
{
|
||||||
if (arguments.size() != 3 && arguments.size() != 4)
|
if (arguments.size() != 3 && arguments.size() != 4)
|
||||||
throw Exception("Function " + getName() + " requires from 3 or 4 parameters: value, min_value, max_value, [max_width_of_bar = 80]. Passed "
|
throw Exception("Function " + getName() + " requires from 3 or 4 parameters: value, min_value, max_value, [max_width_of_bar = 80]. Passed "
|
||||||
@ -673,7 +674,7 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Выполнить функцию над блоком.
|
/// Выполнить функцию над блоком.
|
||||||
void execute(Block & block, const ColumnNumbers & arguments, size_t result)
|
void execute(Block & block, const ColumnNumbers & arguments, size_t result) override
|
||||||
{
|
{
|
||||||
Int64 min = extractConstant<Int64>(block, arguments, 1, "Second"); /// Уровень значения, при котором полоска имеет нулевую длину.
|
Int64 min = extractConstant<Int64>(block, arguments, 1, "Second"); /// Уровень значения, при котором полоска имеет нулевую длину.
|
||||||
Int64 max = extractConstant<Int64>(block, arguments, 2, "Third"); /// Уровень значения, при котором полоска имеет максимальную длину.
|
Int64 max = extractConstant<Int64>(block, arguments, 2, "Third"); /// Уровень значения, при котором полоска имеет максимальную длину.
|
||||||
|
@ -153,13 +153,13 @@ public:
|
|||||||
static IFunction * create(const Context & context) { return new FunctionRandom; }
|
static IFunction * create(const Context & context) { return new FunctionRandom; }
|
||||||
|
|
||||||
/// Получить имя функции.
|
/// Получить имя функции.
|
||||||
String getName() const
|
String getName() const override
|
||||||
{
|
{
|
||||||
return name;
|
return name;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Получить тип результата по типам аргументов. Если функция неприменима для данных аргументов - кинуть исключение.
|
/// Получить тип результата по типам аргументов. Если функция неприменима для данных аргументов - кинуть исключение.
|
||||||
DataTypePtr getReturnType(const DataTypes & arguments) const
|
DataTypePtr getReturnType(const DataTypes & arguments) const override
|
||||||
{
|
{
|
||||||
if (arguments.size() > 1)
|
if (arguments.size() > 1)
|
||||||
throw Exception("Number of arguments for function " + getName() + " doesn't match: passed "
|
throw Exception("Number of arguments for function " + getName() + " doesn't match: passed "
|
||||||
@ -170,7 +170,7 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Выполнить функцию над блоком.
|
/// Выполнить функцию над блоком.
|
||||||
void execute(Block & block, const ColumnNumbers & arguments, size_t result)
|
void execute(Block & block, const ColumnNumbers & arguments, size_t result) override
|
||||||
{
|
{
|
||||||
ColumnVector<ToType> * col_to = new ColumnVector<ToType>;
|
ColumnVector<ToType> * col_to = new ColumnVector<ToType>;
|
||||||
block.getByPosition(result).column = col_to;
|
block.getByPosition(result).column = col_to;
|
||||||
@ -199,13 +199,13 @@ public:
|
|||||||
static IFunction * create(const Context & context) { return new FunctionRandomConstant; }
|
static IFunction * create(const Context & context) { return new FunctionRandomConstant; }
|
||||||
|
|
||||||
/// Получить имя функции.
|
/// Получить имя функции.
|
||||||
String getName() const
|
String getName() const override
|
||||||
{
|
{
|
||||||
return name;
|
return name;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Получить тип результата по типам аргументов. Если функция неприменима для данных аргументов - кинуть исключение.
|
/// Получить тип результата по типам аргументов. Если функция неприменима для данных аргументов - кинуть исключение.
|
||||||
DataTypePtr getReturnType(const DataTypes & arguments) const
|
DataTypePtr getReturnType(const DataTypes & arguments) const override
|
||||||
{
|
{
|
||||||
if (arguments.size() > 1)
|
if (arguments.size() > 1)
|
||||||
throw Exception("Number of arguments for function " + getName() + " doesn't match: passed "
|
throw Exception("Number of arguments for function " + getName() + " doesn't match: passed "
|
||||||
@ -216,7 +216,7 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Выполнить функцию над блоком.
|
/// Выполнить функцию над блоком.
|
||||||
void execute(Block & block, const ColumnNumbers & arguments, size_t result)
|
void execute(Block & block, const ColumnNumbers & arguments, size_t result) override
|
||||||
{
|
{
|
||||||
if (!is_initialized)
|
if (!is_initialized)
|
||||||
{
|
{
|
||||||
|
@ -27,13 +27,13 @@ public:
|
|||||||
static IFunction * create(const Context & context) { return new FunctionReinterpretAsStringImpl; };
|
static IFunction * create(const Context & context) { return new FunctionReinterpretAsStringImpl; };
|
||||||
|
|
||||||
/// Получить имя функции.
|
/// Получить имя функции.
|
||||||
String getName() const
|
String getName() const override
|
||||||
{
|
{
|
||||||
return name;
|
return name;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Получить тип результата по типам аргументов. Если функция неприменима для данных аргументов - кинуть исключение.
|
/// Получить тип результата по типам аргументов. Если функция неприменима для данных аргументов - кинуть исключение.
|
||||||
DataTypePtr getReturnType(const DataTypes & arguments) const
|
DataTypePtr getReturnType(const DataTypes & arguments) const override
|
||||||
{
|
{
|
||||||
if (arguments.size() != 1)
|
if (arguments.size() != 1)
|
||||||
throw Exception("Number of arguments for function " + getName() + " doesn't match: passed "
|
throw Exception("Number of arguments for function " + getName() + " doesn't match: passed "
|
||||||
@ -97,7 +97,7 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Выполнить функцию над блоком.
|
/// Выполнить функцию над блоком.
|
||||||
void execute(Block & block, const ColumnNumbers & arguments, size_t result)
|
void execute(Block & block, const ColumnNumbers & arguments, size_t result) override
|
||||||
{
|
{
|
||||||
if (!( executeType<UInt8>(block, arguments, result)
|
if (!( executeType<UInt8>(block, arguments, result)
|
||||||
|| executeType<UInt16>(block, arguments, result)
|
|| executeType<UInt16>(block, arguments, result)
|
||||||
@ -125,13 +125,13 @@ public:
|
|||||||
typedef typename ToDataType::FieldType ToFieldType;
|
typedef typename ToDataType::FieldType ToFieldType;
|
||||||
|
|
||||||
/// Получить имя функции.
|
/// Получить имя функции.
|
||||||
String getName() const
|
String getName() const override
|
||||||
{
|
{
|
||||||
return name;
|
return name;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Получить тип результата по типам аргументов. Если функция неприменима для данных аргументов - кинуть исключение.
|
/// Получить тип результата по типам аргументов. Если функция неприменима для данных аргументов - кинуть исключение.
|
||||||
DataTypePtr getReturnType(const DataTypes & arguments) const
|
DataTypePtr getReturnType(const DataTypes & arguments) const override
|
||||||
{
|
{
|
||||||
if (arguments.size() != 1)
|
if (arguments.size() != 1)
|
||||||
throw Exception("Number of arguments for function " + getName() + " doesn't match: passed "
|
throw Exception("Number of arguments for function " + getName() + " doesn't match: passed "
|
||||||
@ -147,7 +147,7 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Выполнить функцию над блоком.
|
/// Выполнить функцию над блоком.
|
||||||
void execute(Block & block, const ColumnNumbers & arguments, size_t result)
|
void execute(Block & block, const ColumnNumbers & arguments, size_t result) override
|
||||||
{
|
{
|
||||||
if (ColumnString * col_from = typeid_cast<ColumnString *>(&*block.getByPosition(arguments[0]).column))
|
if (ColumnString * col_from = typeid_cast<ColumnString *>(&*block.getByPosition(arguments[0]).column))
|
||||||
{
|
{
|
||||||
|
@ -3,6 +3,8 @@
|
|||||||
#include <Poco/UTF8Encoding.h>
|
#include <Poco/UTF8Encoding.h>
|
||||||
#include <Poco/Unicode.h>
|
#include <Poco/Unicode.h>
|
||||||
|
|
||||||
|
#include <DB/Core/FieldVisitors.h>
|
||||||
|
|
||||||
#include <DB/DataTypes/DataTypesNumberFixed.h>
|
#include <DB/DataTypes/DataTypesNumberFixed.h>
|
||||||
#include <DB/DataTypes/DataTypeString.h>
|
#include <DB/DataTypes/DataTypeString.h>
|
||||||
#include <DB/DataTypes/DataTypeFixedString.h>
|
#include <DB/DataTypes/DataTypeFixedString.h>
|
||||||
@ -770,13 +772,13 @@ public:
|
|||||||
static IFunction * create(const Context & context) { return new FunctionStringOrArrayToT; }
|
static IFunction * create(const Context & context) { return new FunctionStringOrArrayToT; }
|
||||||
|
|
||||||
/// Получить имя функции.
|
/// Получить имя функции.
|
||||||
String getName() const
|
String getName() const override
|
||||||
{
|
{
|
||||||
return name;
|
return name;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Получить тип результата по типам аргументов. Если функция неприменима для данных аргументов - кинуть исключение.
|
/// Получить тип результата по типам аргументов. Если функция неприменима для данных аргументов - кинуть исключение.
|
||||||
DataTypePtr getReturnType(const DataTypes & arguments) const
|
DataTypePtr getReturnType(const DataTypes & arguments) const override
|
||||||
{
|
{
|
||||||
if (arguments.size() != 1)
|
if (arguments.size() != 1)
|
||||||
throw Exception("Number of arguments for function " + getName() + " doesn't match: passed "
|
throw Exception("Number of arguments for function " + getName() + " doesn't match: passed "
|
||||||
@ -792,7 +794,7 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Выполнить функцию над блоком.
|
/// Выполнить функцию над блоком.
|
||||||
void execute(Block & block, const ColumnNumbers & arguments, size_t result)
|
void execute(Block & block, const ColumnNumbers & arguments, size_t result) override
|
||||||
{
|
{
|
||||||
const ColumnPtr column = block.getByPosition(arguments[0]).column;
|
const ColumnPtr column = block.getByPosition(arguments[0]).column;
|
||||||
if (const ColumnString * col = typeid_cast<const ColumnString *>(&*column))
|
if (const ColumnString * col = typeid_cast<const ColumnString *>(&*column))
|
||||||
@ -866,13 +868,13 @@ public:
|
|||||||
static IFunction * create(const Context & context) { return new FunctionStringToString; }
|
static IFunction * create(const Context & context) { return new FunctionStringToString; }
|
||||||
|
|
||||||
/// Получить имя функции.
|
/// Получить имя функции.
|
||||||
String getName() const
|
String getName() const override
|
||||||
{
|
{
|
||||||
return name;
|
return name;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Получить тип результата по типам аргументов. Если функция неприменима для данных аргументов - кинуть исключение.
|
/// Получить тип результата по типам аргументов. Если функция неприменима для данных аргументов - кинуть исключение.
|
||||||
DataTypePtr getReturnType(const DataTypes & arguments) const
|
DataTypePtr getReturnType(const DataTypes & arguments) const override
|
||||||
{
|
{
|
||||||
if (arguments.size() != 1)
|
if (arguments.size() != 1)
|
||||||
throw Exception("Number of arguments for function " + getName() + " doesn't match: passed "
|
throw Exception("Number of arguments for function " + getName() + " doesn't match: passed "
|
||||||
@ -887,7 +889,7 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Выполнить функцию над блоком.
|
/// Выполнить функцию над блоком.
|
||||||
void execute(Block & block, const ColumnNumbers & arguments, size_t result)
|
void execute(Block & block, const ColumnNumbers & arguments, size_t result) override
|
||||||
{
|
{
|
||||||
const ColumnPtr column = block.getByPosition(arguments[0]).column;
|
const ColumnPtr column = block.getByPosition(arguments[0]).column;
|
||||||
if (const ColumnString * col = typeid_cast<const ColumnString *>(&*column))
|
if (const ColumnString * col = typeid_cast<const ColumnString *>(&*column))
|
||||||
@ -926,13 +928,13 @@ public:
|
|||||||
static IFunction * create(const Context & context) { return new FunctionConcat; }
|
static IFunction * create(const Context & context) { return new FunctionConcat; }
|
||||||
|
|
||||||
/// Получить имя функции.
|
/// Получить имя функции.
|
||||||
String getName() const
|
String getName() const override
|
||||||
{
|
{
|
||||||
return name;
|
return name;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Получить тип результата по типам аргументов. Если функция неприменима для данных аргументов - кинуть исключение.
|
/// Получить тип результата по типам аргументов. Если функция неприменима для данных аргументов - кинуть исключение.
|
||||||
DataTypePtr getReturnType(const DataTypes & arguments) const
|
DataTypePtr getReturnType(const DataTypes & arguments) const override
|
||||||
{
|
{
|
||||||
if (arguments.size() < 2)
|
if (arguments.size() < 2)
|
||||||
throw Exception("Number of arguments for function " + getName() + " doesn't match: passed "
|
throw Exception("Number of arguments for function " + getName() + " doesn't match: passed "
|
||||||
@ -1397,13 +1399,13 @@ public:
|
|||||||
static IFunction * create(const Context & context) { return new FunctionStringNumNumToString; }
|
static IFunction * create(const Context & context) { return new FunctionStringNumNumToString; }
|
||||||
|
|
||||||
/// Получить имя функции.
|
/// Получить имя функции.
|
||||||
String getName() const
|
String getName() const override
|
||||||
{
|
{
|
||||||
return name;
|
return name;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Получить тип результата по типам аргументов. Если функция неприменима для данных аргументов - кинуть исключение.
|
/// Получить тип результата по типам аргументов. Если функция неприменима для данных аргументов - кинуть исключение.
|
||||||
DataTypePtr getReturnType(const DataTypes & arguments) const
|
DataTypePtr getReturnType(const DataTypes & arguments) const override
|
||||||
{
|
{
|
||||||
if (arguments.size() != 3)
|
if (arguments.size() != 3)
|
||||||
throw Exception("Number of arguments for function " + getName() + " doesn't match: passed "
|
throw Exception("Number of arguments for function " + getName() + " doesn't match: passed "
|
||||||
@ -1422,7 +1424,7 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Выполнить функцию над блоком.
|
/// Выполнить функцию над блоком.
|
||||||
void execute(Block & block, const ColumnNumbers & arguments, size_t result)
|
void execute(Block & block, const ColumnNumbers & arguments, size_t result) override
|
||||||
{
|
{
|
||||||
const ColumnPtr column_string = block.getByPosition(arguments[0]).column;
|
const ColumnPtr column_string = block.getByPosition(arguments[0]).column;
|
||||||
const ColumnPtr column_start = block.getByPosition(arguments[1]).column;
|
const ColumnPtr column_start = block.getByPosition(arguments[1]).column;
|
||||||
@ -1477,13 +1479,13 @@ public:
|
|||||||
static constexpr auto name = "appendTrailingCharIfAbsent";
|
static constexpr auto name = "appendTrailingCharIfAbsent";
|
||||||
static IFunction * create(const Context & context) { return new FunctionAppendTrailingCharIfAbsent; }
|
static IFunction * create(const Context & context) { return new FunctionAppendTrailingCharIfAbsent; }
|
||||||
|
|
||||||
String getName() const
|
String getName() const override
|
||||||
{
|
{
|
||||||
return name;
|
return name;
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
DataTypePtr getReturnType(const DataTypes & arguments) const
|
DataTypePtr getReturnType(const DataTypes & arguments) const override
|
||||||
{
|
{
|
||||||
if (arguments.size() != 2)
|
if (arguments.size() != 2)
|
||||||
throw Exception{
|
throw Exception{
|
||||||
|
@ -316,13 +316,13 @@ public:
|
|||||||
static IFunction * create(const Context & context) { return new FunctionTokens; }
|
static IFunction * create(const Context & context) { return new FunctionTokens; }
|
||||||
|
|
||||||
/// Получить имя функции.
|
/// Получить имя функции.
|
||||||
String getName() const
|
String getName() const override
|
||||||
{
|
{
|
||||||
return name;
|
return name;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Получить тип результата по типам аргументов. Если функция неприменима для данных аргументов - кинуть исключение.
|
/// Получить тип результата по типам аргументов. Если функция неприменима для данных аргументов - кинуть исключение.
|
||||||
DataTypePtr getReturnType(const DataTypes & arguments) const
|
DataTypePtr getReturnType(const DataTypes & arguments) const override
|
||||||
{
|
{
|
||||||
Generator::checkArguments(arguments);
|
Generator::checkArguments(arguments);
|
||||||
|
|
||||||
@ -330,7 +330,7 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Выполнить функцию над блоком.
|
/// Выполнить функцию над блоком.
|
||||||
void execute(Block & block, const ColumnNumbers & arguments, size_t result)
|
void execute(Block & block, const ColumnNumbers & arguments, size_t result) override
|
||||||
{
|
{
|
||||||
Generator generator;
|
Generator generator;
|
||||||
generator.init(block, arguments);
|
generator.init(block, arguments);
|
||||||
|
@ -75,7 +75,7 @@ struct PositionImpl
|
|||||||
while (pos < end && end != (pos = searcher.search(pos, end - pos)))
|
while (pos < end && end != (pos = searcher.search(pos, end - pos)))
|
||||||
{
|
{
|
||||||
/// Определим, к какому индексу оно относится.
|
/// Определим, к какому индексу оно относится.
|
||||||
while (begin + offsets[i] < pos)
|
while (begin + offsets[i] <= pos)
|
||||||
{
|
{
|
||||||
res[i] = 0;
|
res[i] = 0;
|
||||||
++i;
|
++i;
|
||||||
@ -163,7 +163,7 @@ struct PositionUTF8Impl
|
|||||||
while (pos < end && end != (pos = searcher.search(pos, end - pos)))
|
while (pos < end && end != (pos = searcher.search(pos, end - pos)))
|
||||||
{
|
{
|
||||||
/// Определим, к какому индексу оно относится.
|
/// Определим, к какому индексу оно относится.
|
||||||
while (begin + offsets[i] < pos)
|
while (begin + offsets[i] <= pos)
|
||||||
{
|
{
|
||||||
res[i] = 0;
|
res[i] = 0;
|
||||||
++i;
|
++i;
|
||||||
@ -364,7 +364,7 @@ public:
|
|||||||
while (pos < end && end != (pos = searcher.find(pos, end)))
|
while (pos < end && end != (pos = searcher.find(pos, end)))
|
||||||
{
|
{
|
||||||
/// Определим, к какому индексу оно относится.
|
/// Определим, к какому индексу оно относится.
|
||||||
while (begin + offsets[i] < pos)
|
while (begin + offsets[i] <= pos)
|
||||||
{
|
{
|
||||||
res[i] = 0;
|
res[i] = 0;
|
||||||
++i;
|
++i;
|
||||||
@ -627,7 +627,7 @@ public:
|
|||||||
while (pos < end && end != (pos = searcher.find(pos, end)))
|
while (pos < end && end != (pos = searcher.find(pos, end)))
|
||||||
{
|
{
|
||||||
/// Определим, к какому индексу оно относится.
|
/// Определим, к какому индексу оно относится.
|
||||||
while (begin + offsets[i] < pos)
|
while (begin + offsets[i] <= pos)
|
||||||
{
|
{
|
||||||
res[i] = 0;
|
res[i] = 0;
|
||||||
++i;
|
++i;
|
||||||
@ -898,7 +898,7 @@ struct MatchImpl
|
|||||||
while (pos < end && end != (pos = searcher.search(pos, end - pos)))
|
while (pos < end && end != (pos = searcher.search(pos, end - pos)))
|
||||||
{
|
{
|
||||||
/// Определим, к какому индексу оно относится.
|
/// Определим, к какому индексу оно относится.
|
||||||
while (begin + offsets[i] < pos)
|
while (begin + offsets[i] <= pos)
|
||||||
{
|
{
|
||||||
res[i] = revert;
|
res[i] = revert;
|
||||||
++i;
|
++i;
|
||||||
@ -965,7 +965,7 @@ struct MatchImpl
|
|||||||
while (pos < end && end != (pos = searcher.search(pos, end - pos)))
|
while (pos < end && end != (pos = searcher.search(pos, end - pos)))
|
||||||
{
|
{
|
||||||
/// Определим, к какому индексу оно относится.
|
/// Определим, к какому индексу оно относится.
|
||||||
while (begin + offsets[i] < pos)
|
while (begin + offsets[i] <= pos)
|
||||||
{
|
{
|
||||||
res[i] = revert;
|
res[i] = revert;
|
||||||
++i;
|
++i;
|
||||||
@ -1361,7 +1361,7 @@ struct ReplaceStringImpl
|
|||||||
memcpy(&res_data[res_offset], pos, match - pos);
|
memcpy(&res_data[res_offset], pos, match - pos);
|
||||||
|
|
||||||
/// Определим, к какому индексу оно относится.
|
/// Определим, к какому индексу оно относится.
|
||||||
while (i < offsets.size() && begin + offsets[i] < match)
|
while (i < offsets.size() && begin + offsets[i] <= match)
|
||||||
{
|
{
|
||||||
res_offsets[i] = res_offset + ((begin + offsets[i]) - pos);
|
res_offsets[i] = res_offset + ((begin + offsets[i]) - pos);
|
||||||
++i;
|
++i;
|
||||||
@ -1398,6 +1398,7 @@ struct ReplaceStringImpl
|
|||||||
res_offset += (begin + offsets[i] - pos);
|
res_offset += (begin + offsets[i] - pos);
|
||||||
res_offsets[i] = res_offset;
|
res_offsets[i] = res_offset;
|
||||||
pos = begin + offsets[i];
|
pos = begin + offsets[i];
|
||||||
|
++i;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1430,7 +1431,7 @@ struct ReplaceStringImpl
|
|||||||
memcpy(&res_data[res_offset], pos, match - pos);
|
memcpy(&res_data[res_offset], pos, match - pos);
|
||||||
|
|
||||||
/// Определим, к какому индексу оно относится.
|
/// Определим, к какому индексу оно относится.
|
||||||
while (i < size && begin + n * (i + 1) < match)
|
while (i < size && begin + n * (i + 1) <= match)
|
||||||
{
|
{
|
||||||
res_offsets[i] = res_offset + ((begin + n * (i + 1)) - pos);
|
res_offsets[i] = res_offset + ((begin + n * (i + 1)) - pos);
|
||||||
++i;
|
++i;
|
||||||
@ -1504,13 +1505,13 @@ public:
|
|||||||
static IFunction * create(const Context & context) { return new FunctionStringReplace; }
|
static IFunction * create(const Context & context) { return new FunctionStringReplace; }
|
||||||
|
|
||||||
/// Получить имя функции.
|
/// Получить имя функции.
|
||||||
String getName() const
|
String getName() const override
|
||||||
{
|
{
|
||||||
return name;
|
return name;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Получить тип результата по типам аргументов. Если функция неприменима для данных аргументов - кинуть исключение.
|
/// Получить тип результата по типам аргументов. Если функция неприменима для данных аргументов - кинуть исключение.
|
||||||
DataTypePtr getReturnType(const DataTypes & arguments) const
|
DataTypePtr getReturnType(const DataTypes & arguments) const override
|
||||||
{
|
{
|
||||||
if (arguments.size() != 3)
|
if (arguments.size() != 3)
|
||||||
throw Exception("Number of arguments for function " + getName() + " doesn't match: passed "
|
throw Exception("Number of arguments for function " + getName() + " doesn't match: passed "
|
||||||
@ -1533,7 +1534,7 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Выполнить функцию над блоком.
|
/// Выполнить функцию над блоком.
|
||||||
void execute(Block & block, const ColumnNumbers & arguments, size_t result)
|
void execute(Block & block, const ColumnNumbers & arguments, size_t result) override
|
||||||
{
|
{
|
||||||
const ColumnPtr column_src = block.getByPosition(arguments[0]).column;
|
const ColumnPtr column_src = block.getByPosition(arguments[0]).column;
|
||||||
const ColumnPtr column_needle = block.getByPosition(arguments[1]).column;
|
const ColumnPtr column_needle = block.getByPosition(arguments[1]).column;
|
||||||
@ -1591,13 +1592,13 @@ public:
|
|||||||
static IFunction * create(const Context & context) { return new FunctionsStringSearch; }
|
static IFunction * create(const Context & context) { return new FunctionsStringSearch; }
|
||||||
|
|
||||||
/// Получить имя функции.
|
/// Получить имя функции.
|
||||||
String getName() const
|
String getName() const override
|
||||||
{
|
{
|
||||||
return name;
|
return name;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Получить тип результата по типам аргументов. Если функция неприменима для данных аргументов - кинуть исключение.
|
/// Получить тип результата по типам аргументов. Если функция неприменима для данных аргументов - кинуть исключение.
|
||||||
DataTypePtr getReturnType(const DataTypes & arguments) const
|
DataTypePtr getReturnType(const DataTypes & arguments) const override
|
||||||
{
|
{
|
||||||
if (arguments.size() != 2)
|
if (arguments.size() != 2)
|
||||||
throw Exception("Number of arguments for function " + getName() + " doesn't match: passed "
|
throw Exception("Number of arguments for function " + getName() + " doesn't match: passed "
|
||||||
@ -1616,7 +1617,7 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Выполнить функцию над блоком.
|
/// Выполнить функцию над блоком.
|
||||||
void execute(Block & block, const ColumnNumbers & arguments, size_t result)
|
void execute(Block & block, const ColumnNumbers & arguments, size_t result) override
|
||||||
{
|
{
|
||||||
typedef typename Impl::ResultType ResultType;
|
typedef typename Impl::ResultType ResultType;
|
||||||
|
|
||||||
@ -1660,13 +1661,13 @@ public:
|
|||||||
static IFunction * create(const Context & context) { return new FunctionsStringSearchToString; }
|
static IFunction * create(const Context & context) { return new FunctionsStringSearchToString; }
|
||||||
|
|
||||||
/// Получить имя функции.
|
/// Получить имя функции.
|
||||||
String getName() const
|
String getName() const override
|
||||||
{
|
{
|
||||||
return name;
|
return name;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Получить тип результата по типам аргументов. Если функция неприменима для данных аргументов - кинуть исключение.
|
/// Получить тип результата по типам аргументов. Если функция неприменима для данных аргументов - кинуть исключение.
|
||||||
DataTypePtr getReturnType(const DataTypes & arguments) const
|
DataTypePtr getReturnType(const DataTypes & arguments) const override
|
||||||
{
|
{
|
||||||
if (arguments.size() != 2)
|
if (arguments.size() != 2)
|
||||||
throw Exception("Number of arguments for function " + getName() + " doesn't match: passed "
|
throw Exception("Number of arguments for function " + getName() + " doesn't match: passed "
|
||||||
@ -1685,7 +1686,7 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Выполнить функцию над блоком.
|
/// Выполнить функцию над блоком.
|
||||||
void execute(Block & block, const ColumnNumbers & arguments, size_t result)
|
void execute(Block & block, const ColumnNumbers & arguments, size_t result) override
|
||||||
{
|
{
|
||||||
const ColumnPtr column = block.getByPosition(arguments[0]).column;
|
const ColumnPtr column = block.getByPosition(arguments[0]).column;
|
||||||
const ColumnPtr column_needle = block.getByPosition(arguments[1]).column;
|
const ColumnPtr column_needle = block.getByPosition(arguments[1]).column;
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
#include <mutex>
|
#include <mutex>
|
||||||
|
|
||||||
|
#include <DB/Core/FieldVisitors.h>
|
||||||
#include <DB/DataTypes/DataTypesNumberFixed.h>
|
#include <DB/DataTypes/DataTypesNumberFixed.h>
|
||||||
#include <DB/DataTypes/DataTypeString.h>
|
#include <DB/DataTypes/DataTypeString.h>
|
||||||
#include <DB/DataTypes/DataTypeArray.h>
|
#include <DB/DataTypes/DataTypeArray.h>
|
||||||
|
@ -306,7 +306,7 @@ struct ExtractParamImpl
|
|||||||
while (pos < end && end != (pos = searcher.search(pos, end - pos)))
|
while (pos < end && end != (pos = searcher.search(pos, end - pos)))
|
||||||
{
|
{
|
||||||
/// Определим, к какому индексу оно относится.
|
/// Определим, к какому индексу оно относится.
|
||||||
while (begin + offsets[i] < pos)
|
while (begin + offsets[i] <= pos)
|
||||||
{
|
{
|
||||||
res[i] = 0;
|
res[i] = 0;
|
||||||
++i;
|
++i;
|
||||||
@ -369,7 +369,7 @@ struct ExtractParamToStringImpl
|
|||||||
while (pos < end && end != (pos = searcher.search(pos, end - pos)))
|
while (pos < end && end != (pos = searcher.search(pos, end - pos)))
|
||||||
{
|
{
|
||||||
/// Определим, к какому индексу оно относится.
|
/// Определим, к какому индексу оно относится.
|
||||||
while (begin + offsets[i] < pos)
|
while (begin + offsets[i] <= pos)
|
||||||
{
|
{
|
||||||
res_data.push_back(0);
|
res_data.push_back(0);
|
||||||
res_offsets[i] = res_data.size();
|
res_offsets[i] = res_data.size();
|
||||||
|
@ -293,23 +293,7 @@ public:
|
|||||||
*/
|
*/
|
||||||
ColumnPtr execute(const Block & block, bool negative) const;
|
ColumnPtr execute(const Block & block, bool negative) const;
|
||||||
|
|
||||||
std::string describe() const
|
std::string describe() const;
|
||||||
{
|
|
||||||
if (!ordered_set_elements)
|
|
||||||
return "{}";
|
|
||||||
|
|
||||||
bool first = true;
|
|
||||||
std::stringstream ss;
|
|
||||||
|
|
||||||
ss << "{";
|
|
||||||
for (const Field & f : *ordered_set_elements)
|
|
||||||
{
|
|
||||||
ss << (first ? "" : ", ") << apply_visitor(FieldVisitorToString(), f);
|
|
||||||
first = false;
|
|
||||||
}
|
|
||||||
ss << "}";
|
|
||||||
return ss.str();
|
|
||||||
}
|
|
||||||
|
|
||||||
/// проверяет есть ли в Set элементы для заданного диапазона индекса
|
/// проверяет есть ли в Set элементы для заданного диапазона индекса
|
||||||
BoolMask mayBeTrueInRange(const Range & range) const;
|
BoolMask mayBeTrueInRange(const Range & range) const;
|
||||||
|
@ -5,6 +5,8 @@
|
|||||||
#include <Poco/Timespan.h>
|
#include <Poco/Timespan.h>
|
||||||
#include <cpuid/libcpuid.h>
|
#include <cpuid/libcpuid.h>
|
||||||
#include <DB/IO/CompressedStream.h>
|
#include <DB/IO/CompressedStream.h>
|
||||||
|
#include <DB/IO/ReadHelpers.h>
|
||||||
|
|
||||||
|
|
||||||
namespace DB
|
namespace DB
|
||||||
{
|
{
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <DB/Core/Field.h>
|
#include <DB/Core/Field.h>
|
||||||
|
#include <DB/Core/FieldVisitors.h>
|
||||||
#include <DB/DataTypes/IDataType.h>
|
#include <DB/DataTypes/IDataType.h>
|
||||||
#include <DB/Parsers/ASTWithAlias.h>
|
#include <DB/Parsers/ASTWithAlias.h>
|
||||||
|
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <DB/Core/Field.h>
|
#include <DB/Core/Field.h>
|
||||||
|
#include <DB/Core/FieldVisitors.h>
|
||||||
#include <DB/Parsers/IAST.h>
|
#include <DB/Parsers/IAST.h>
|
||||||
|
|
||||||
|
|
||||||
|
@ -225,6 +225,11 @@ private:
|
|||||||
|
|
||||||
std::size_t getIdentifiersColumnSize(const IdentifierNameSet & identifiers) const
|
std::size_t getIdentifiersColumnSize(const IdentifierNameSet & identifiers) const
|
||||||
{
|
{
|
||||||
|
/** for expressions containing no columns (or where columns could not be determined otherwise) assume maximum
|
||||||
|
* possible size so they do not have priority in eligibility over other expressions. */
|
||||||
|
if (identifiers.empty())
|
||||||
|
return std::numeric_limits<std::size_t>::max();
|
||||||
|
|
||||||
std::size_t size{};
|
std::size_t size{};
|
||||||
|
|
||||||
for (const auto & identifier : identifiers)
|
for (const auto & identifier : identifiers)
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
|
|
||||||
|
#include <DB/Core/FieldVisitors.h>
|
||||||
#include <DB/Interpreters/Context.h>
|
#include <DB/Interpreters/Context.h>
|
||||||
#include <DB/Core/SortDescription.h>
|
#include <DB/Core/SortDescription.h>
|
||||||
#include <DB/Parsers/ASTExpressionList.h>
|
#include <DB/Parsers/ASTExpressionList.h>
|
||||||
|
@ -1,4 +1,6 @@
|
|||||||
#include <DB/AggregateFunctions/AggregateFunctionFactory.h>
|
#include <DB/AggregateFunctions/AggregateFunctionFactory.h>
|
||||||
|
#include <DB/IO/WriteBuffer.h>
|
||||||
|
#include <DB/IO/WriteHelpers.h>
|
||||||
#include <DB/DataTypes/DataTypeAggregateFunction.h>
|
#include <DB/DataTypes/DataTypeAggregateFunction.h>
|
||||||
#include <DB/DataTypes/DataTypeArray.h>
|
#include <DB/DataTypes/DataTypeArray.h>
|
||||||
|
|
||||||
|
141
dbms/src/Core/Field.cpp
Normal file
141
dbms/src/Core/Field.cpp
Normal file
@ -0,0 +1,141 @@
|
|||||||
|
#include <DB/IO/ReadBuffer.h>
|
||||||
|
#include <DB/IO/WriteBuffer.h>
|
||||||
|
#include <DB/IO/ReadHelpers.h>
|
||||||
|
#include <DB/IO/WriteHelpers.h>
|
||||||
|
#include <DB/IO/ReadBufferFromString.h>
|
||||||
|
#include <DB/IO/WriteBufferFromString.h>
|
||||||
|
|
||||||
|
#include <DB/Core/Field.h>
|
||||||
|
#include <DB/Core/FieldVisitors.h>
|
||||||
|
|
||||||
|
|
||||||
|
namespace mysqlxx
|
||||||
|
{
|
||||||
|
std::ostream & operator<< (mysqlxx::EscapeManipResult res, const DB::Array & value)
|
||||||
|
{
|
||||||
|
return res.ostr << apply_visitor(DB::FieldVisitorToString(), value);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::ostream & operator<< (mysqlxx::QuoteManipResult res, const DB::Array & value)
|
||||||
|
{
|
||||||
|
throw Poco::Exception("Cannot quote Array with mysqlxx::quote.");
|
||||||
|
}
|
||||||
|
|
||||||
|
std::istream & operator>> (mysqlxx::UnEscapeManipResult res, DB::Array & value)
|
||||||
|
{
|
||||||
|
throw Poco::Exception("Cannot unescape Array with mysqlxx::unescape.");
|
||||||
|
}
|
||||||
|
|
||||||
|
std::istream & operator>> (mysqlxx::UnQuoteManipResult res, DB::Array & value)
|
||||||
|
{
|
||||||
|
throw Poco::Exception("Cannot unquote Array with mysqlxx::unquote.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
namespace DB
|
||||||
|
{
|
||||||
|
inline void readBinary(Array & x, ReadBuffer & buf)
|
||||||
|
{
|
||||||
|
size_t size;
|
||||||
|
UInt8 type;
|
||||||
|
DB::readBinary(type, buf);
|
||||||
|
DB::readBinary(size, buf);
|
||||||
|
|
||||||
|
for (size_t index = 0; index < size; ++index)
|
||||||
|
{
|
||||||
|
switch (type)
|
||||||
|
{
|
||||||
|
case Field::Types::Null:
|
||||||
|
{
|
||||||
|
x.push_back(DB::Field());
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case Field::Types::UInt64:
|
||||||
|
{
|
||||||
|
UInt64 value;
|
||||||
|
DB::readVarUInt(value, buf);
|
||||||
|
x.push_back(value);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case Field::Types::Int64:
|
||||||
|
{
|
||||||
|
Int64 value;
|
||||||
|
DB::readVarInt(value, buf);
|
||||||
|
x.push_back(value);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case Field::Types::Float64:
|
||||||
|
{
|
||||||
|
Float64 value;
|
||||||
|
DB::readFloatBinary(value, buf);
|
||||||
|
x.push_back(value);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case Field::Types::String:
|
||||||
|
{
|
||||||
|
std::string value;
|
||||||
|
DB::readStringBinary(value, buf);
|
||||||
|
x.push_back(value);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case Field::Types::Array:
|
||||||
|
{
|
||||||
|
Array value;
|
||||||
|
DB::readBinary(value, buf);
|
||||||
|
x.push_back(value);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void writeBinary(const Array & x, WriteBuffer & buf)
|
||||||
|
{
|
||||||
|
UInt8 type = Field::Types::Null;
|
||||||
|
size_t size = x.size();
|
||||||
|
if (size)
|
||||||
|
type = x.front().getType();
|
||||||
|
DB::writeBinary(type, buf);
|
||||||
|
DB::writeBinary(size, buf);
|
||||||
|
|
||||||
|
for (Array::const_iterator it = x.begin(); it != x.end(); ++it)
|
||||||
|
{
|
||||||
|
switch (type)
|
||||||
|
{
|
||||||
|
case Field::Types::Null: break;
|
||||||
|
case Field::Types::UInt64:
|
||||||
|
{
|
||||||
|
DB::writeVarUInt(get<UInt64>(*it), buf);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case Field::Types::Int64:
|
||||||
|
{
|
||||||
|
DB::writeVarInt(get<Int64>(*it), buf);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case Field::Types::Float64:
|
||||||
|
{
|
||||||
|
DB::writeFloatBinary(get<Float64>(*it), buf);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case Field::Types::String:
|
||||||
|
{
|
||||||
|
DB::writeStringBinary(get<std::string>(*it), buf);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case Field::Types::Array:
|
||||||
|
{
|
||||||
|
DB::writeBinary(get<Array>(*it), buf);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void writeText(const Array & x, WriteBuffer & buf)
|
||||||
|
{
|
||||||
|
DB::String res = apply_visitor(DB::FieldVisitorToString(), DB::Field(x));
|
||||||
|
buf.write(res.data(), res.size());
|
||||||
|
}
|
||||||
|
}
|
88
dbms/src/Core/FieldVisitors.cpp
Normal file
88
dbms/src/Core/FieldVisitors.cpp
Normal file
@ -0,0 +1,88 @@
|
|||||||
|
#include <DB/Core/FieldVisitors.h>
|
||||||
|
|
||||||
|
|
||||||
|
namespace DB
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
String FieldVisitorDump::operator() (const String & x) const
|
||||||
|
{
|
||||||
|
String res;
|
||||||
|
WriteBufferFromString wb(res);
|
||||||
|
writeQuoted(x, wb);
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
String FieldVisitorDump::operator() (const Array & x) const
|
||||||
|
{
|
||||||
|
String res;
|
||||||
|
WriteBufferFromString wb(res);
|
||||||
|
FieldVisitorDump visitor;
|
||||||
|
|
||||||
|
wb.write("Array_[", 7);
|
||||||
|
for (Array::const_iterator it = x.begin(); it != x.end(); ++it)
|
||||||
|
{
|
||||||
|
if (it != x.begin())
|
||||||
|
wb.write(", ", 2);
|
||||||
|
writeString(apply_visitor(visitor, *it), wb);
|
||||||
|
}
|
||||||
|
writeChar(']', wb);
|
||||||
|
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
String FieldVisitorToString::formatFloat(const Float64 x)
|
||||||
|
{
|
||||||
|
char tmp[25];
|
||||||
|
double_conversion::StringBuilder builder{tmp, sizeof(tmp)};
|
||||||
|
|
||||||
|
const auto result = getDoubleToStringConverter().ToShortest(x, &builder);
|
||||||
|
|
||||||
|
if (!result)
|
||||||
|
throw Exception("Cannot print float or double number", ErrorCodes::CANNOT_PRINT_FLOAT_OR_DOUBLE_NUMBER);
|
||||||
|
|
||||||
|
return { tmp, tmp + builder.position() };
|
||||||
|
}
|
||||||
|
|
||||||
|
String FieldVisitorToString::operator() (const Array & x) const
|
||||||
|
{
|
||||||
|
String res;
|
||||||
|
WriteBufferFromString wb(res);
|
||||||
|
FieldVisitorToString visitor;
|
||||||
|
|
||||||
|
writeChar('[', wb);
|
||||||
|
for (Array::const_iterator it = x.begin(); it != x.end(); ++it)
|
||||||
|
{
|
||||||
|
if (it != x.begin())
|
||||||
|
wb.write(", ", 2);
|
||||||
|
writeString(apply_visitor(visitor, *it), wb);
|
||||||
|
}
|
||||||
|
writeChar(']', wb);
|
||||||
|
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
UInt64 stringToDateOrDateTime(const String & s)
|
||||||
|
{
|
||||||
|
ReadBufferFromString in(s);
|
||||||
|
|
||||||
|
if (s.size() == strlen("YYYY-MM-DD"))
|
||||||
|
{
|
||||||
|
DayNum_t date{};
|
||||||
|
readDateText(date, in);
|
||||||
|
return UInt64(date);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
time_t date_time{};
|
||||||
|
readDateTimeText(date_time, in);
|
||||||
|
if (!in.eof())
|
||||||
|
throw Exception("String is too long for DateTime: " + s);
|
||||||
|
return UInt64(date_time);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
@ -1,5 +1,9 @@
|
|||||||
#include <DB/Core/NamesAndTypes.h>
|
#include <DB/Core/NamesAndTypes.h>
|
||||||
#include <DB/DataTypes/DataTypeFactory.h>
|
#include <DB/DataTypes/DataTypeFactory.h>
|
||||||
|
#include <DB/IO/ReadBuffer.h>
|
||||||
|
#include <DB/IO/WriteBuffer.h>
|
||||||
|
#include <DB/IO/ReadHelpers.h>
|
||||||
|
#include <DB/IO/WriteHelpers.h>
|
||||||
|
|
||||||
|
|
||||||
namespace DB
|
namespace DB
|
||||||
|
@ -3,6 +3,7 @@
|
|||||||
#include <sstream>
|
#include <sstream>
|
||||||
|
|
||||||
#include <DB/Core/Field.h>
|
#include <DB/Core/Field.h>
|
||||||
|
#include <DB/Core/FieldVisitors.h>
|
||||||
|
|
||||||
#include <DB/Common/Stopwatch.h>
|
#include <DB/Common/Stopwatch.h>
|
||||||
#include <DB/DataStreams/TabSeparatedRowOutputStream.h>
|
#include <DB/DataStreams/TabSeparatedRowOutputStream.h>
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
#include <DB/Core/FieldVisitors.h>
|
||||||
#include <DB/DataStreams/CollapsingSortedBlockInputStream.h>
|
#include <DB/DataStreams/CollapsingSortedBlockInputStream.h>
|
||||||
|
|
||||||
/// Максимальное количество сообщений о некорректных данных в логе.
|
/// Максимальное количество сообщений о некорректных данных в логе.
|
||||||
|
@ -1,3 +1,5 @@
|
|||||||
|
#include <DB/Core/FieldVisitors.h>
|
||||||
|
|
||||||
#include <DB/IO/WriteHelpers.h>
|
#include <DB/IO/WriteHelpers.h>
|
||||||
#include <DB/IO/ReadHelpers.h>
|
#include <DB/IO/ReadHelpers.h>
|
||||||
|
|
||||||
@ -13,6 +15,30 @@ namespace DB
|
|||||||
using Poco::SharedPtr;
|
using Poco::SharedPtr;
|
||||||
|
|
||||||
|
|
||||||
|
std::string DataTypeAggregateFunction::getName() const
|
||||||
|
{
|
||||||
|
std::stringstream stream;
|
||||||
|
stream << "AggregateFunction(" << function->getName();
|
||||||
|
|
||||||
|
if (!parameters.empty())
|
||||||
|
{
|
||||||
|
stream << "(";
|
||||||
|
for (size_t i = 0; i < parameters.size(); ++i)
|
||||||
|
{
|
||||||
|
if (i)
|
||||||
|
stream << ", ";
|
||||||
|
stream << apply_visitor(DB::FieldVisitorToString(), parameters[i]);
|
||||||
|
}
|
||||||
|
stream << ")";
|
||||||
|
}
|
||||||
|
|
||||||
|
for (DataTypes::const_iterator it = argument_types.begin(); it != argument_types.end(); ++it)
|
||||||
|
stream << ", " << (*it)->getName();
|
||||||
|
|
||||||
|
stream << ")";
|
||||||
|
return stream.str();
|
||||||
|
}
|
||||||
|
|
||||||
void DataTypeAggregateFunction::serializeBinary(const Field & field, WriteBuffer & ostr) const
|
void DataTypeAggregateFunction::serializeBinary(const Field & field, WriteBuffer & ostr) const
|
||||||
{
|
{
|
||||||
const String & s = get<const String &>(field);
|
const String & s = get<const String &>(field);
|
||||||
|
@ -1,5 +1,8 @@
|
|||||||
#include <Poco/SharedPtr.h>
|
#include <Poco/SharedPtr.h>
|
||||||
|
|
||||||
|
#include <DB/IO/WriteBuffer.h>
|
||||||
|
#include <DB/IO/WriteHelpers.h>
|
||||||
|
|
||||||
#include <DB/Columns/ColumnFixedString.h>
|
#include <DB/Columns/ColumnFixedString.h>
|
||||||
#include <DB/Columns/ColumnsNumber.h>
|
#include <DB/Columns/ColumnsNumber.h>
|
||||||
#include <DB/Columns/ColumnConst.h>
|
#include <DB/Columns/ColumnConst.h>
|
||||||
@ -17,6 +20,12 @@ namespace DB
|
|||||||
using Poco::SharedPtr;
|
using Poco::SharedPtr;
|
||||||
|
|
||||||
|
|
||||||
|
std::string DataTypeFixedString::getName() const
|
||||||
|
{
|
||||||
|
return "FixedString(" + toString(n) + ")";
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void DataTypeFixedString::serializeBinary(const Field & field, WriteBuffer & ostr) const
|
void DataTypeFixedString::serializeBinary(const Field & field, WriteBuffer & ostr) const
|
||||||
{
|
{
|
||||||
const String & s = get<const String &>(field);
|
const String & s = get<const String &>(field);
|
||||||
|
@ -1,5 +1,7 @@
|
|||||||
|
#include <DB/Core/FieldVisitors.h>
|
||||||
#include <DB/DataTypes/FieldToDataType.h>
|
#include <DB/DataTypes/FieldToDataType.h>
|
||||||
|
|
||||||
|
|
||||||
namespace DB
|
namespace DB
|
||||||
{
|
{
|
||||||
|
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
#include <DB/Core/Field.h>
|
#include <DB/Core/Field.h>
|
||||||
|
#include <DB/Core/FieldVisitors.h>
|
||||||
|
|
||||||
#include <DB/Columns/ColumnString.h>
|
#include <DB/Columns/ColumnString.h>
|
||||||
#include <DB/Columns/ColumnFixedString.h>
|
#include <DB/Columns/ColumnFixedString.h>
|
||||||
@ -230,144 +231,97 @@ bool Set::insertFromBlock(const Block & block, bool create_ordered_set)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/** Чтобы корректно работали выражения вида 1.0 IN (1).
|
/** Проверка попадания Field from, имеющим тип From в диапазон значений типа To.
|
||||||
|
* From и To - числовые типы. Могут быть типами с плавающей запятой.
|
||||||
|
* From - это одно из UInt64, Int64, Float64,
|
||||||
|
* тогда как To может быть также 8, 16, 32 битным.
|
||||||
|
*
|
||||||
|
* Если попадает в диапазон, то from конвертируется в Field ближайшего к To типа.
|
||||||
|
* Если не попадает - возвращается Field(Null).
|
||||||
|
*/
|
||||||
|
|
||||||
|
template <typename From, typename To>
|
||||||
|
static Field convertNumericTypeImpl(const Field & from)
|
||||||
|
{
|
||||||
|
From value = from.get<From>();
|
||||||
|
|
||||||
|
if (static_cast<long double>(value) != static_cast<long double>(To(value)))
|
||||||
|
return {};
|
||||||
|
|
||||||
|
return Field(typename NearestFieldType<To>::Type(value));
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename To>
|
||||||
|
static Field convertNumericType(const Field & from, const IDataType & type)
|
||||||
|
{
|
||||||
|
if (from.getType() == Field::Types::UInt64)
|
||||||
|
return convertNumericTypeImpl<UInt64, To>(from);
|
||||||
|
if (from.getType() == Field::Types::Int64)
|
||||||
|
return convertNumericTypeImpl<Int64, To>(from);
|
||||||
|
if (from.getType() == Field::Types::Float64)
|
||||||
|
return convertNumericTypeImpl<Float64, To>(from);
|
||||||
|
|
||||||
|
throw Exception("Type mismatch in IN section: " + type.getName() + " at left, "
|
||||||
|
+ Field::Types::toString(from.getType()) + " at right", ErrorCodes::TYPE_MISMATCH);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/** Чтобы корректно работали выражения вида 1.0 IN (1) или чтобы 1 IN (1, 2.0, 2.5, -1) работало так же, как 1 IN (1, 2).
|
||||||
* Проверяет совместимость типов, проверяет попадание значений в диапазон допустимых значений типа, делает преобразование типа.
|
* Проверяет совместимость типов, проверяет попадание значений в диапазон допустимых значений типа, делает преобразование типа.
|
||||||
* Код слегка дурацкий.
|
* Если значение не попадает в диапазон - возвращает Null.
|
||||||
*/
|
*/
|
||||||
static Field convertToType(const Field & src, const IDataType & type)
|
static Field convertToType(const Field & src, const IDataType & type)
|
||||||
{
|
{
|
||||||
if (type.isNumeric())
|
if (type.isNumeric())
|
||||||
{
|
{
|
||||||
bool is_uint8 = false;
|
if (typeid_cast<const DataTypeUInt8 *>(&type)) return convertNumericType<UInt8>(src, type);
|
||||||
bool is_uint16 = false;
|
if (typeid_cast<const DataTypeUInt16 *>(&type)) return convertNumericType<UInt16>(src, type);
|
||||||
bool is_uint32 = false;
|
if (typeid_cast<const DataTypeUInt32 *>(&type)) return convertNumericType<UInt32>(src, type);
|
||||||
bool is_uint64 = false;
|
if (typeid_cast<const DataTypeUInt64 *>(&type)) return convertNumericType<UInt64>(src, type);
|
||||||
bool is_int8 = false;
|
if (typeid_cast<const DataTypeInt8 *>(&type)) return convertNumericType<Int8>(src, type);
|
||||||
bool is_int16 = false;
|
if (typeid_cast<const DataTypeInt16 *>(&type)) return convertNumericType<Int16>(src, type);
|
||||||
bool is_int32 = false;
|
if (typeid_cast<const DataTypeInt32 *>(&type)) return convertNumericType<Int32>(src, type);
|
||||||
bool is_int64 = false;
|
if (typeid_cast<const DataTypeInt64 *>(&type)) return convertNumericType<Int64>(src, type);
|
||||||
bool is_float32 = false;
|
if (typeid_cast<const DataTypeFloat32 *>(&type)) return convertNumericType<Float32>(src, type);
|
||||||
bool is_float64 = false;
|
if (typeid_cast<const DataTypeFloat64 *>(&type)) return convertNumericType<Float64>(src, type);
|
||||||
bool is_date = false;
|
|
||||||
bool is_datetime = false;
|
|
||||||
|
|
||||||
false
|
bool is_date = typeid_cast<const DataTypeDate *>(&type);
|
||||||
|| (is_uint8 = typeid_cast<const DataTypeUInt8 * >(&type))
|
bool is_datetime = typeid_cast<const DataTypeDateTime *>(&type);
|
||||||
|| (is_uint16 = typeid_cast<const DataTypeUInt16 * >(&type))
|
|
||||||
|| (is_uint32 = typeid_cast<const DataTypeUInt32 * >(&type))
|
|
||||||
|| (is_uint64 = typeid_cast<const DataTypeUInt64 * >(&type))
|
|
||||||
|| (is_int8 = typeid_cast<const DataTypeInt8 * >(&type))
|
|
||||||
|| (is_int16 = typeid_cast<const DataTypeInt16 * >(&type))
|
|
||||||
|| (is_int32 = typeid_cast<const DataTypeInt32 * >(&type))
|
|
||||||
|| (is_int64 = typeid_cast<const DataTypeInt64 * >(&type))
|
|
||||||
|| (is_float32 = typeid_cast<const DataTypeFloat32 * >(&type))
|
|
||||||
|| (is_float64 = typeid_cast<const DataTypeFloat64 * >(&type))
|
|
||||||
|| (is_date = typeid_cast<const DataTypeDate * >(&type))
|
|
||||||
|| (is_datetime = typeid_cast<const DataTypeDateTime * >(&type))
|
|
||||||
;
|
|
||||||
|
|
||||||
if (is_uint8 || is_uint16 || is_uint32 || is_uint64)
|
if (!is_date && !is_datetime)
|
||||||
|
throw Exception("Logical error: unknown numeric type " + type.getName(), ErrorCodes::LOGICAL_ERROR);
|
||||||
|
|
||||||
|
if (src.getType() == Field::Types::UInt64)
|
||||||
|
return src;
|
||||||
|
|
||||||
|
if (src.getType() == Field::Types::String)
|
||||||
{
|
{
|
||||||
if (src.getType() == Field::Types::Int64)
|
/// Возможность сравнивать даты и даты-с-временем со строкой.
|
||||||
throw Exception("Type mismatch in IN section: " + type.getName() + " at left, signed at right");
|
const String & str = src.get<const String &>();
|
||||||
|
ReadBufferFromString in(str);
|
||||||
|
|
||||||
if (src.getType() == Field::Types::Float64)
|
if (is_date)
|
||||||
throw Exception("Type mismatch in IN section: " + type.getName() + " at left, floating point at right");
|
|
||||||
|
|
||||||
if (src.getType() == Field::Types::UInt64)
|
|
||||||
{
|
{
|
||||||
UInt64 value = src.get<const UInt64 &>();
|
DayNum_t date{};
|
||||||
if ((is_uint8 && value > std::numeric_limits<uint8_t>::max())
|
readDateText(date, in);
|
||||||
|| (is_uint16 && value > std::numeric_limits<uint16_t>::max())
|
if (!in.eof())
|
||||||
|| (is_uint32 && value > std::numeric_limits<uint32_t>::max()))
|
throw Exception("String is too long for Date: " + str);
|
||||||
throw Exception("Value (" + toString(value) + ") in IN section is out of range of type " + type.getName() + " at left");
|
|
||||||
|
|
||||||
return src;
|
return Field(UInt64(date));
|
||||||
}
|
}
|
||||||
|
else
|
||||||
throw Exception("Type mismatch in IN section: " + type.getName() + " at left, "
|
|
||||||
+ Field::Types::toString(src.getType()) + " at right");
|
|
||||||
}
|
|
||||||
else if (is_int8 || is_int16 || is_int32 || is_int64)
|
|
||||||
{
|
|
||||||
if (src.getType() == Field::Types::Float64)
|
|
||||||
throw Exception("Type mismatch in IN section: " + type.getName() + " at left, floating point at right");
|
|
||||||
|
|
||||||
if (src.getType() == Field::Types::UInt64)
|
|
||||||
{
|
{
|
||||||
UInt64 value = src.get<const UInt64 &>();
|
time_t date_time{};
|
||||||
|
readDateTimeText(date_time, in);
|
||||||
|
if (!in.eof())
|
||||||
|
throw Exception("String is too long for DateTime: " + str);
|
||||||
|
|
||||||
if ((is_int8 && value > uint8_t(std::numeric_limits<int8_t>::max()))
|
return Field(UInt64(date_time));
|
||||||
|| (is_int16 && value > uint16_t(std::numeric_limits<int16_t>::max()))
|
|
||||||
|| (is_int32 && value > uint32_t(std::numeric_limits<int32_t>::max()))
|
|
||||||
|| (is_int64 && value > uint64_t(std::numeric_limits<int64_t>::max())))
|
|
||||||
throw Exception("Value (" + toString(value) + ") in IN section is out of range of type " + type.getName() + " at left");
|
|
||||||
|
|
||||||
return Field(Int64(value));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (src.getType() == Field::Types::Int64)
|
|
||||||
{
|
|
||||||
Int64 value = src.get<const Int64 &>();
|
|
||||||
if ((is_int8 && (value < std::numeric_limits<int8_t>::min() || value > std::numeric_limits<int8_t>::max()))
|
|
||||||
|| (is_int16 && (value < std::numeric_limits<int16_t>::min() || value > std::numeric_limits<int16_t>::max()))
|
|
||||||
|| (is_int32 && (value < std::numeric_limits<int32_t>::min() || value > std::numeric_limits<int32_t>::max())))
|
|
||||||
throw Exception("Value (" + toString(value) + ") in IN section is out of range of type " + type.getName() + " at left");
|
|
||||||
|
|
||||||
return src;
|
|
||||||
}
|
|
||||||
|
|
||||||
throw Exception("Type mismatch in IN section: " + type.getName() + " at left, "
|
|
||||||
+ Field::Types::toString(src.getType()) + " at right");
|
|
||||||
}
|
}
|
||||||
else if (is_float32 || is_float64)
|
|
||||||
{
|
|
||||||
if (src.getType() == Field::Types::UInt64)
|
|
||||||
return Field(Float64(src.get<UInt64>()));
|
|
||||||
|
|
||||||
if (src.getType() == Field::Types::Int64)
|
throw Exception("Type mismatch in IN section: " + type.getName() + " at left, "
|
||||||
return Field(Float64(src.get<Int64>()));
|
+ Field::Types::toString(src.getType()) + " at right", ErrorCodes::TYPE_MISMATCH);
|
||||||
|
|
||||||
if (src.getType() == Field::Types::Float64)
|
|
||||||
return src;
|
|
||||||
|
|
||||||
throw Exception("Type mismatch in IN section: " + type.getName() + " at left, "
|
|
||||||
+ Field::Types::toString(src.getType()) + " at right");
|
|
||||||
}
|
|
||||||
else if (is_date || is_datetime)
|
|
||||||
{
|
|
||||||
if (src.getType() == Field::Types::UInt64)
|
|
||||||
return src;
|
|
||||||
|
|
||||||
if (src.getType() == Field::Types::String)
|
|
||||||
{
|
|
||||||
/// Возможность сравнивать даты и даты-с-временем со строкой.
|
|
||||||
const String & str = src.get<const String &>();
|
|
||||||
ReadBufferFromString in(str);
|
|
||||||
|
|
||||||
if (is_date)
|
|
||||||
{
|
|
||||||
DayNum_t date{};
|
|
||||||
readDateText(date, in);
|
|
||||||
if (!in.eof())
|
|
||||||
throw Exception("String is too long for Date: " + str);
|
|
||||||
|
|
||||||
return Field(UInt64(date));
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
time_t date_time{};
|
|
||||||
readDateTimeText(date_time, in);
|
|
||||||
if (!in.eof())
|
|
||||||
throw Exception("String is too long for DateTime: " + str);
|
|
||||||
|
|
||||||
return Field(UInt64(date_time));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
throw Exception("Type mismatch in IN section: " + type.getName() + " at left, "
|
|
||||||
+ Field::Types::toString(src.getType()) + " at right");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -381,7 +335,7 @@ static Field convertToType(const Field & src, const IDataType & type)
|
|||||||
|| (src.getType() == Field::Types::Array
|
|| (src.getType() == Field::Types::Array
|
||||||
&& !typeid_cast<const DataTypeArray *>(&type)))
|
&& !typeid_cast<const DataTypeArray *>(&type)))
|
||||||
throw Exception("Type mismatch in IN section: " + type.getName() + " at left, "
|
throw Exception("Type mismatch in IN section: " + type.getName() + " at left, "
|
||||||
+ Field::Types::toString(src.getType()) + " at right");
|
+ Field::Types::toString(src.getType()) + " at right", ErrorCodes::TYPE_MISMATCH);
|
||||||
}
|
}
|
||||||
|
|
||||||
return src;
|
return src;
|
||||||
@ -448,7 +402,10 @@ void Set::createFromAST(DataTypes & types, ASTPtr node, const Context & context,
|
|||||||
{
|
{
|
||||||
if (data_types.size() == 1)
|
if (data_types.size() == 1)
|
||||||
{
|
{
|
||||||
block.getByPosition(0).column->insert(extractValueFromNode(*it, *data_types[0], context));
|
Field value = extractValueFromNode(*it, *data_types[0], context);
|
||||||
|
|
||||||
|
if (!value.isNull())
|
||||||
|
block.getByPosition(0).column->insert(value);
|
||||||
}
|
}
|
||||||
else if (ASTFunction * func = typeid_cast<ASTFunction *>(&**it))
|
else if (ASTFunction * func = typeid_cast<ASTFunction *>(&**it))
|
||||||
{
|
{
|
||||||
@ -461,7 +418,10 @@ void Set::createFromAST(DataTypes & types, ASTPtr node, const Context & context,
|
|||||||
|
|
||||||
for (size_t j = 0; j < tuple_size; ++j)
|
for (size_t j = 0; j < tuple_size; ++j)
|
||||||
{
|
{
|
||||||
block.getByPosition(j).column->insert(extractValueFromNode(func->arguments->children[j], *data_types[j], context));
|
Field value = extractValueFromNode(func->arguments->children[j], *data_types[j], context);
|
||||||
|
|
||||||
|
if (!value.isNull())
|
||||||
|
block.getByPosition(j).column->insert(value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -719,4 +679,23 @@ BoolMask Set::mayBeTrueInRange(const Range & range) const
|
|||||||
return BoolMask(can_be_true, can_be_false);
|
return BoolMask(can_be_true, can_be_false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
std::string Set::describe() const
|
||||||
|
{
|
||||||
|
if (!ordered_set_elements)
|
||||||
|
return "{}";
|
||||||
|
|
||||||
|
bool first = true;
|
||||||
|
std::stringstream ss;
|
||||||
|
|
||||||
|
ss << "{";
|
||||||
|
for (const Field & f : *ordered_set_elements)
|
||||||
|
{
|
||||||
|
ss << (first ? "" : ", ") << apply_visitor(FieldVisitorToString(), f);
|
||||||
|
first = false;
|
||||||
|
}
|
||||||
|
ss << "}";
|
||||||
|
return ss.str();
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
#include <DB/Common/SipHash.h>
|
#include <DB/Common/SipHash.h>
|
||||||
|
#include <DB/Core/FieldVisitors.h>
|
||||||
#include <DB/Parsers/ASTLiteral.h>
|
#include <DB/Parsers/ASTLiteral.h>
|
||||||
|
|
||||||
|
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
#include <DB/Core/FieldVisitors.h>
|
||||||
#include <DB/Parsers/ASTSetQuery.h>
|
#include <DB/Parsers/ASTSetQuery.h>
|
||||||
#include <DB/Parsers/ASTSelectQuery.h>
|
#include <DB/Parsers/ASTSelectQuery.h>
|
||||||
|
|
||||||
|
@ -50,8 +50,8 @@ void OLAPHTTPHandler::processQuery(Poco::Net::HTTPServerRequest & request, Poco:
|
|||||||
Context context = *server.global_context;
|
Context context = *server.global_context;
|
||||||
context.setGlobalContext(*server.global_context);
|
context.setGlobalContext(*server.global_context);
|
||||||
|
|
||||||
context.setUser(user, password, request.clientAddress().host(), quota_key);
|
|
||||||
context.setSetting("profile", profile);
|
context.setSetting("profile", profile);
|
||||||
|
context.setUser(user, password, request.clientAddress().host(), quota_key);
|
||||||
|
|
||||||
context.setInterface(Context::Interface::OLAP_HTTP);
|
context.setInterface(Context::Interface::OLAP_HTTP);
|
||||||
context.setHTTPMethod(Context::HTTPMethod::POST);
|
context.setHTTPMethod(Context::HTTPMethod::POST);
|
||||||
|
@ -48,7 +48,7 @@ void QueryConverter::OLAPServerQueryToClickHouse(const QueryParseResult & query,
|
|||||||
if (query.format != FORMAT_TAB)
|
if (query.format != FORMAT_TAB)
|
||||||
throw Exception("Only tab-separated output format is supported", ErrorCodes::UNSUPPORTED_PARAMETER);
|
throw Exception("Only tab-separated output format is supported", ErrorCodes::UNSUPPORTED_PARAMETER);
|
||||||
|
|
||||||
/// Учтем некоторые настройки (пока далеко не все).
|
/// Учтем некоторые настройки (далеко не все).
|
||||||
|
|
||||||
Settings new_settings = inout_context.getSettings();
|
Settings new_settings = inout_context.getSettings();
|
||||||
|
|
||||||
@ -61,17 +61,20 @@ void QueryConverter::OLAPServerQueryToClickHouse(const QueryParseResult & query,
|
|||||||
if (query.max_result_size != 0)
|
if (query.max_result_size != 0)
|
||||||
new_settings.limits.max_rows_to_group_by = query.max_result_size;
|
new_settings.limits.max_rows_to_group_by = query.max_result_size;
|
||||||
|
|
||||||
switch (query.overflow_mode)
|
if (query.has_overflow_mode)
|
||||||
{
|
{
|
||||||
case OLAP::OVERFLOW_MODE_THROW:
|
switch (query.overflow_mode)
|
||||||
new_settings.limits.group_by_overflow_mode = DB::OverflowMode::THROW;
|
{
|
||||||
break;
|
case OLAP::OVERFLOW_MODE_THROW:
|
||||||
case OLAP::OVERFLOW_MODE_BREAK:
|
new_settings.limits.group_by_overflow_mode = DB::OverflowMode::THROW;
|
||||||
new_settings.limits.group_by_overflow_mode = DB::OverflowMode::BREAK;
|
break;
|
||||||
break;
|
case OLAP::OVERFLOW_MODE_BREAK:
|
||||||
case OLAP::OVERFLOW_MODE_ANY:
|
new_settings.limits.group_by_overflow_mode = DB::OverflowMode::BREAK;
|
||||||
new_settings.limits.group_by_overflow_mode = DB::OverflowMode::ANY;
|
break;
|
||||||
break;
|
case OLAP::OVERFLOW_MODE_ANY:
|
||||||
|
new_settings.limits.group_by_overflow_mode = DB::OverflowMode::ANY;
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
inout_context.setSettings(new_settings);
|
inout_context.setSettings(new_settings);
|
||||||
|
@ -100,7 +100,6 @@ QueryParseResult QueryParser::parse(std::istream & s)
|
|||||||
|
|
||||||
result.cut_date_last = false;
|
result.cut_date_last = false;
|
||||||
result.cut_dates_for_goals = false;
|
result.cut_dates_for_goals = false;
|
||||||
result.overflow_mode = OVERFLOW_MODE_THROW;
|
|
||||||
result.concurrency = 0;
|
result.concurrency = 0;
|
||||||
result.max_threads_per_counter = 0;
|
result.max_threads_per_counter = 0;
|
||||||
result.limit = 0;
|
result.limit = 0;
|
||||||
@ -152,9 +151,10 @@ QueryParseResult QueryParser::parse(std::istream & s)
|
|||||||
throw Exception(std::string("Unknown overflow mode: ") + overflow_mode_str,
|
throw Exception(std::string("Unknown overflow mode: ") + overflow_mode_str,
|
||||||
ErrorCodes::UNKNOWN_OVERFLOW_MODE);
|
ErrorCodes::UNKNOWN_OVERFLOW_MODE);
|
||||||
|
|
||||||
|
result.has_overflow_mode = true;
|
||||||
result.overflow_mode = overflow_mode_str == "throw" ? OVERFLOW_MODE_THROW
|
result.overflow_mode = overflow_mode_str == "throw" ? OVERFLOW_MODE_THROW
|
||||||
: (overflow_mode_str == "break" ? OVERFLOW_MODE_BREAK
|
: (overflow_mode_str == "break" ? OVERFLOW_MODE_BREAK
|
||||||
: OVERFLOW_MODE_ANY);
|
: OVERFLOW_MODE_ANY);
|
||||||
}
|
}
|
||||||
else if (settings_child_nodes->item(i)->nodeName() == "concurrency")
|
else if (settings_child_nodes->item(i)->nodeName() == "concurrency")
|
||||||
{
|
{
|
||||||
|
@ -87,6 +87,8 @@ struct QueryParseResult
|
|||||||
float sample;
|
float sample;
|
||||||
|
|
||||||
Format format;
|
Format format;
|
||||||
|
|
||||||
|
bool has_overflow_mode = false;
|
||||||
OverflowMode overflow_mode;
|
OverflowMode overflow_mode;
|
||||||
|
|
||||||
Poco::AutoPtr<Poco::XML::Document> query;
|
Poco::AutoPtr<Poco::XML::Document> query;
|
||||||
|
@ -1,4 +1,8 @@
|
|||||||
#include <DB/Parsers/ExpressionListParsers.h>
|
#include <DB/Parsers/ExpressionListParsers.h>
|
||||||
|
#include <DB/IO/WriteBuffer.h>
|
||||||
|
#include <DB/IO/WriteHelpers.h>
|
||||||
|
#include <DB/IO/ReadBuffer.h>
|
||||||
|
#include <DB/IO/ReadHelpers.h>
|
||||||
#include <DB/IO/WriteBufferFromString.h>
|
#include <DB/IO/WriteBufferFromString.h>
|
||||||
#include <DB/Storages/ColumnsDescription.h>
|
#include <DB/Storages/ColumnsDescription.h>
|
||||||
#include <DB/DataTypes/DataTypeFactory.h>
|
#include <DB/DataTypes/DataTypeFactory.h>
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
#include <DB/Core/FieldVisitors.h>
|
||||||
#include <DB/Storages/MergeTree/MergeTreeDataSelectExecutor.h>
|
#include <DB/Storages/MergeTree/MergeTreeDataSelectExecutor.h>
|
||||||
#include <DB/Storages/MergeTree/MergeTreeBlockInputStream.h>
|
#include <DB/Storages/MergeTree/MergeTreeBlockInputStream.h>
|
||||||
#include <DB/Storages/MergeTree/MergeTreeReadPool.h>
|
#include <DB/Storages/MergeTree/MergeTreeReadPool.h>
|
||||||
@ -389,6 +390,10 @@ BlockInputStreams MergeTreeDataSelectExecutor::spreadMarkRangesAmongThreads(
|
|||||||
|
|
||||||
if (sum_marks > 0 && settings.merge_tree_uniform_read_distribution == 1)
|
if (sum_marks > 0 && settings.merge_tree_uniform_read_distribution == 1)
|
||||||
{
|
{
|
||||||
|
/// Уменьшим количество потоков, если данных мало.
|
||||||
|
if (sum_marks < threads * min_marks_for_concurrent_read && parts.size() < threads)
|
||||||
|
threads = std::max((sum_marks + min_marks_for_concurrent_read - 1) / min_marks_for_concurrent_read, parts.size());
|
||||||
|
|
||||||
MergeTreeReadPoolPtr pool = std::make_shared<MergeTreeReadPool>(
|
MergeTreeReadPoolPtr pool = std::make_shared<MergeTreeReadPool>(
|
||||||
threads, sum_marks, min_marks_for_concurrent_read, parts, data, prewhere_actions, prewhere_column, true,
|
threads, sum_marks, min_marks_for_concurrent_read, parts, data, prewhere_actions, prewhere_column, true,
|
||||||
column_names);
|
column_names);
|
||||||
|
@ -63,130 +63,6 @@ const PKCondition::AtomMap PKCondition::atom_map{
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
/// Преобразование строки с датой или датой-с-временем в UInt64, содержащим числовое значение даты или даты-с-временем.
|
|
||||||
UInt64 stringToDateOrDateTime(const String & s)
|
|
||||||
{
|
|
||||||
ReadBufferFromString in(s);
|
|
||||||
|
|
||||||
if (s.size() == strlen("YYYY-MM-DD"))
|
|
||||||
{
|
|
||||||
DayNum_t date{};
|
|
||||||
readDateText(date, in);
|
|
||||||
return UInt64(date);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
time_t date_time{};
|
|
||||||
readDateTimeText(date_time, in);
|
|
||||||
if (!in.eof())
|
|
||||||
throw Exception("String is too long for DateTime: " + s);
|
|
||||||
return UInt64(date_time);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
#pragma GCC diagnostic push
|
|
||||||
#pragma GCC diagnostic ignored "-Wsign-compare"
|
|
||||||
|
|
||||||
/** Более точное сравнение.
|
|
||||||
* Отличается от Field::operator< и Field::operator== тем, что сравнивает значения разных числовых типов между собой.
|
|
||||||
* Правила сравнения - такие же, что и в FunctionsComparison.
|
|
||||||
* В том числе, сравнение знаковых и беззнаковых оставляем UB.
|
|
||||||
*/
|
|
||||||
class FieldVisitorAccurateEquals : public StaticVisitor<bool>
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
bool operator() (const Null & l, const Null & r) const { return true; }
|
|
||||||
bool operator() (const Null & l, const UInt64 & r) const { return false; }
|
|
||||||
bool operator() (const Null & l, const Int64 & r) const { return false; }
|
|
||||||
bool operator() (const Null & l, const Float64 & r) const { return false; }
|
|
||||||
bool operator() (const Null & l, const String & r) const { return false; }
|
|
||||||
bool operator() (const Null & l, const Array & r) const { return false; }
|
|
||||||
|
|
||||||
bool operator() (const UInt64 & l, const Null & r) const { return false; }
|
|
||||||
bool operator() (const UInt64 & l, const UInt64 & r) const { return l == r; }
|
|
||||||
bool operator() (const UInt64 & l, const Int64 & r) const { return l == r; }
|
|
||||||
bool operator() (const UInt64 & l, const Float64 & r) const { return l == r; }
|
|
||||||
bool operator() (const UInt64 & l, const String & r) const { return l == stringToDateOrDateTime(r); }
|
|
||||||
bool operator() (const UInt64 & l, const Array & r) const { return false; }
|
|
||||||
|
|
||||||
bool operator() (const Int64 & l, const Null & r) const { return false; }
|
|
||||||
bool operator() (const Int64 & l, const UInt64 & r) const { return l == r; }
|
|
||||||
bool operator() (const Int64 & l, const Int64 & r) const { return l == r; }
|
|
||||||
bool operator() (const Int64 & l, const Float64 & r) const { return l == r; }
|
|
||||||
bool operator() (const Int64 & l, const String & r) const { return false; }
|
|
||||||
bool operator() (const Int64 & l, const Array & r) const { return false; }
|
|
||||||
|
|
||||||
bool operator() (const Float64 & l, const Null & r) const { return false; }
|
|
||||||
bool operator() (const Float64 & l, const UInt64 & r) const { return l == r; }
|
|
||||||
bool operator() (const Float64 & l, const Int64 & r) const { return l == r; }
|
|
||||||
bool operator() (const Float64 & l, const Float64 & r) const { return l == r; }
|
|
||||||
bool operator() (const Float64 & l, const String & r) const { return false; }
|
|
||||||
bool operator() (const Float64 & l, const Array & r) const { return false; }
|
|
||||||
|
|
||||||
bool operator() (const String & l, const Null & r) const { return false; }
|
|
||||||
bool operator() (const String & l, const UInt64 & r) const { return stringToDateOrDateTime(l) == r; }
|
|
||||||
bool operator() (const String & l, const Int64 & r) const { return false; }
|
|
||||||
bool operator() (const String & l, const Float64 & r) const { return false; }
|
|
||||||
bool operator() (const String & l, const String & r) const { return l == r; }
|
|
||||||
bool operator() (const String & l, const Array & r) const { return false; }
|
|
||||||
|
|
||||||
bool operator() (const Array & l, const Null & r) const { return false; }
|
|
||||||
bool operator() (const Array & l, const UInt64 & r) const { return false; }
|
|
||||||
bool operator() (const Array & l, const Int64 & r) const { return false; }
|
|
||||||
bool operator() (const Array & l, const Float64 & r) const { return false; }
|
|
||||||
bool operator() (const Array & l, const String & r) const { return false; }
|
|
||||||
bool operator() (const Array & l, const Array & r) const { return l == r; }
|
|
||||||
};
|
|
||||||
|
|
||||||
class FieldVisitorAccurateLess : public StaticVisitor<bool>
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
bool operator() (const Null & l, const Null & r) const { return false; }
|
|
||||||
bool operator() (const Null & l, const UInt64 & r) const { return true; }
|
|
||||||
bool operator() (const Null & l, const Int64 & r) const { return true; }
|
|
||||||
bool operator() (const Null & l, const Float64 & r) const { return true; }
|
|
||||||
bool operator() (const Null & l, const String & r) const { return true; }
|
|
||||||
bool operator() (const Null & l, const Array & r) const { return true; }
|
|
||||||
|
|
||||||
bool operator() (const UInt64 & l, const Null & r) const { return false; }
|
|
||||||
bool operator() (const UInt64 & l, const UInt64 & r) const { return l < r; }
|
|
||||||
bool operator() (const UInt64 & l, const Int64 & r) const { return l < r; }
|
|
||||||
bool operator() (const UInt64 & l, const Float64 & r) const { return l < r; }
|
|
||||||
bool operator() (const UInt64 & l, const String & r) const { return l < stringToDateOrDateTime(r); }
|
|
||||||
bool operator() (const UInt64 & l, const Array & r) const { return true; }
|
|
||||||
|
|
||||||
bool operator() (const Int64 & l, const Null & r) const { return false; }
|
|
||||||
bool operator() (const Int64 & l, const UInt64 & r) const { return l < r; }
|
|
||||||
bool operator() (const Int64 & l, const Int64 & r) const { return l < r; }
|
|
||||||
bool operator() (const Int64 & l, const Float64 & r) const { return l < r; }
|
|
||||||
bool operator() (const Int64 & l, const String & r) const { return true; }
|
|
||||||
bool operator() (const Int64 & l, const Array & r) const { return true; }
|
|
||||||
|
|
||||||
bool operator() (const Float64 & l, const Null & r) const { return false; }
|
|
||||||
bool operator() (const Float64 & l, const UInt64 & r) const { return l < r; }
|
|
||||||
bool operator() (const Float64 & l, const Int64 & r) const { return l < r; }
|
|
||||||
bool operator() (const Float64 & l, const Float64 & r) const { return l < r; }
|
|
||||||
bool operator() (const Float64 & l, const String & r) const { return true; }
|
|
||||||
bool operator() (const Float64 & l, const Array & r) const { return true; }
|
|
||||||
|
|
||||||
bool operator() (const String & l, const Null & r) const { return false; }
|
|
||||||
bool operator() (const String & l, const UInt64 & r) const { return stringToDateOrDateTime(l) < r; }
|
|
||||||
bool operator() (const String & l, const Int64 & r) const { return false; }
|
|
||||||
bool operator() (const String & l, const Float64 & r) const { return false; }
|
|
||||||
bool operator() (const String & l, const String & r) const { return l < r; }
|
|
||||||
bool operator() (const String & l, const Array & r) const { return true; }
|
|
||||||
|
|
||||||
bool operator() (const Array & l, const Null & r) const { return false; }
|
|
||||||
bool operator() (const Array & l, const UInt64 & r) const { return false; }
|
|
||||||
bool operator() (const Array & l, const Int64 & r) const { return false; }
|
|
||||||
bool operator() (const Array & l, const Float64 & r) const { return false; }
|
|
||||||
bool operator() (const Array & l, const String & r) const { return false; }
|
|
||||||
bool operator() (const Array & l, const Array & r) const { return l < r; }
|
|
||||||
};
|
|
||||||
|
|
||||||
#pragma GCC diagnostic pop
|
|
||||||
|
|
||||||
|
|
||||||
inline bool Range::equals(const Field & lhs, const Field & rhs) { return apply_visitor(FieldVisitorAccurateEquals(), lhs, rhs); }
|
inline bool Range::equals(const Field & lhs, const Field & rhs) { return apply_visitor(FieldVisitorAccurateEquals(), lhs, rhs); }
|
||||||
inline bool Range::less(const Field & lhs, const Field & rhs) { return apply_visitor(FieldVisitorAccurateLess(), lhs, rhs); }
|
inline bool Range::less(const Field & lhs, const Field & rhs) { return apply_visitor(FieldVisitorAccurateLess(), lhs, rhs); }
|
||||||
|
@ -1,6 +1,8 @@
|
|||||||
#include <Poco/Util/Application.h>
|
#include <Poco/Util/Application.h>
|
||||||
#include <Poco/Util/AbstractConfiguration.h>
|
#include <Poco/Util/AbstractConfiguration.h>
|
||||||
|
|
||||||
|
#include <DB/Core/FieldVisitors.h>
|
||||||
|
|
||||||
#include <DB/Parsers/ASTCreateQuery.h>
|
#include <DB/Parsers/ASTCreateQuery.h>
|
||||||
#include <DB/Parsers/ASTIdentifier.h>
|
#include <DB/Parsers/ASTIdentifier.h>
|
||||||
#include <DB/Parsers/ASTLiteral.h>
|
#include <DB/Parsers/ASTLiteral.h>
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
#include <DB/Core/FieldVisitors.h>
|
||||||
#include <DB/Storages/StorageMergeTree.h>
|
#include <DB/Storages/StorageMergeTree.h>
|
||||||
#include <DB/Storages/MergeTree/MergeTreeBlockOutputStream.h>
|
#include <DB/Storages/MergeTree/MergeTreeBlockOutputStream.h>
|
||||||
#include <DB/Storages/MergeTree/DiskSpaceMonitor.h>
|
#include <DB/Storages/MergeTree/DiskSpaceMonitor.h>
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
#include <ext/range.hpp>
|
#include <ext/range.hpp>
|
||||||
|
#include <DB/Core/FieldVisitors.h>
|
||||||
#include <DB/Storages/ColumnsDescription.h>
|
#include <DB/Storages/ColumnsDescription.h>
|
||||||
#include <DB/Storages/StorageReplicatedMergeTree.h>
|
#include <DB/Storages/StorageReplicatedMergeTree.h>
|
||||||
#include <DB/Storages/MergeTree/ReplicatedMergeTreeBlockOutputStream.h>
|
#include <DB/Storages/MergeTree/ReplicatedMergeTreeBlockOutputStream.h>
|
||||||
|
@ -0,0 +1,14 @@
|
|||||||
|
1 1
|
||||||
|
1 1
|
||||||
|
1 0
|
||||||
|
1 1 1 1 0 1
|
||||||
|
0
|
||||||
|
0
|
||||||
|
1
|
||||||
|
0
|
||||||
|
0
|
||||||
|
1
|
||||||
|
0
|
||||||
|
0
|
||||||
|
0
|
||||||
|
0
|
@ -0,0 +1,13 @@
|
|||||||
|
select 1 as x, x = 1 or x = 2 or x = 3 or x = -1;
|
||||||
|
select 1 as x, x = 1.0 or x = 2 or x = 3 or x = -1;
|
||||||
|
select 1 as x, x = 1.5 or x = 2 or x = 3 or x = -1;
|
||||||
|
|
||||||
|
SELECT
|
||||||
|
1 IN (1, -1, 2.0, 2.5),
|
||||||
|
1.0 IN (1, -1, 2.0, 2.5),
|
||||||
|
1 IN (1.0, -1, 2.0, 2.5),
|
||||||
|
1.0 IN (1.0, -1, 2.0, 2.5),
|
||||||
|
1 IN (1.1, -1, 2.0, 2.5),
|
||||||
|
-1 IN (1, -1, 2.0, 2.5);
|
||||||
|
|
||||||
|
SELECT -number IN (1, 2, 3, -5.0, -2.0) FROM system.numbers LIMIT 10;
|
@ -0,0 +1,192 @@
|
|||||||
|
. . . 1
|
||||||
|
. . . 1
|
||||||
|
. . . 1
|
||||||
|
._ .o .o 1
|
||||||
|
. . . 1
|
||||||
|
_. o. o. 1
|
||||||
|
. . . 1
|
||||||
|
_._ o.o o.o 1
|
||||||
|
._ .o .o 1
|
||||||
|
. . . 1
|
||||||
|
._ .o .o 1
|
||||||
|
._ .o .o 1
|
||||||
|
._ .o .o 1
|
||||||
|
_. o. o. 1
|
||||||
|
._ .o .o 1
|
||||||
|
_._ o.o o.o 1
|
||||||
|
_. o. o. 1
|
||||||
|
. . . 1
|
||||||
|
_. o. o. 1
|
||||||
|
._ .o .o 1
|
||||||
|
_. o. o. 1
|
||||||
|
_. o. o. 1
|
||||||
|
_. o. o. 1
|
||||||
|
_._ o.o o.o 1
|
||||||
|
_._ o.o o.o 1
|
||||||
|
. . . 1
|
||||||
|
_._ o.o o.o 1
|
||||||
|
._ .o .o 1
|
||||||
|
_._ o.o o.o 1
|
||||||
|
_. o. o. 1
|
||||||
|
_._ o.o o.o 1
|
||||||
|
_._ o.o o.o 1
|
||||||
|
. . . 1
|
||||||
|
. . . 1
|
||||||
|
. . . 1
|
||||||
|
._ .oo .oo 1
|
||||||
|
. . . 1
|
||||||
|
_. oo. oo. 1
|
||||||
|
. . . 1
|
||||||
|
_._ oo.oo oo.oo 1
|
||||||
|
._ .oo .oo 1
|
||||||
|
. . . 1
|
||||||
|
._ .oo .oo 1
|
||||||
|
._ .oo .oo 1
|
||||||
|
._ .oo .oo 1
|
||||||
|
_. oo. oo. 1
|
||||||
|
._ .oo .oo 1
|
||||||
|
_._ oo.oo oo.oo 1
|
||||||
|
_. oo. oo. 1
|
||||||
|
. . . 1
|
||||||
|
_. oo. oo. 1
|
||||||
|
._ .oo .oo 1
|
||||||
|
_. oo. oo. 1
|
||||||
|
_. oo. oo. 1
|
||||||
|
_. oo. oo. 1
|
||||||
|
_._ oo.oo oo.oo 1
|
||||||
|
_._ oo.oo oo.oo 1
|
||||||
|
. . . 1
|
||||||
|
_._ oo.oo oo.oo 1
|
||||||
|
._ .oo .oo 1
|
||||||
|
_._ oo.oo oo.oo 1
|
||||||
|
_. oo. oo. 1
|
||||||
|
_._ oo.oo oo.oo 1
|
||||||
|
_._ oo.oo oo.oo 1
|
||||||
|
. . . 1
|
||||||
|
. . . 1
|
||||||
|
. . . 1
|
||||||
|
.__ .oo .oo 1
|
||||||
|
. . . 1
|
||||||
|
__. oo. oo. 1
|
||||||
|
. . . 1
|
||||||
|
__.__ oo.oo oo.oo 1
|
||||||
|
.__ .oo .oo 1
|
||||||
|
. . . 1
|
||||||
|
.__ .oo .oo 1
|
||||||
|
.__ .oo .oo 1
|
||||||
|
.__ .oo .oo 1
|
||||||
|
__. oo. oo. 1
|
||||||
|
.__ .oo .oo 1
|
||||||
|
__.__ oo.oo oo.oo 1
|
||||||
|
__. oo. oo. 1
|
||||||
|
. . . 1
|
||||||
|
__. oo. oo. 1
|
||||||
|
.__ .oo .oo 1
|
||||||
|
__. oo. oo. 1
|
||||||
|
__. oo. oo. 1
|
||||||
|
__. oo. oo. 1
|
||||||
|
__.__ oo.oo oo.oo 1
|
||||||
|
__.__ oo.oo oo.oo 1
|
||||||
|
. . . 1
|
||||||
|
__.__ oo.oo oo.oo 1
|
||||||
|
.__ .oo .oo 1
|
||||||
|
__.__ oo.oo oo.oo 1
|
||||||
|
__. oo. oo. 1
|
||||||
|
__.__ oo.oo oo.oo 1
|
||||||
|
__.__ oo.oo oo.oo 1
|
||||||
|
. . . 1
|
||||||
|
. . . 1
|
||||||
|
. . . 1
|
||||||
|
._ .o .o 1
|
||||||
|
. . . 1
|
||||||
|
_. o. o. 1
|
||||||
|
. . . 1
|
||||||
|
_._ o._ o._ 1
|
||||||
|
._ .o .o 1
|
||||||
|
. . . 1
|
||||||
|
._ .o .o 1
|
||||||
|
._ .o .o 1
|
||||||
|
._ .o .o 1
|
||||||
|
_. o. o. 1
|
||||||
|
._ .o .o 1
|
||||||
|
_._ o._ o._ 1
|
||||||
|
_. o. o. 1
|
||||||
|
. . . 1
|
||||||
|
_. o. o. 1
|
||||||
|
._ .o .o 1
|
||||||
|
_. o. o. 1
|
||||||
|
_. o. o. 1
|
||||||
|
_. o. o. 1
|
||||||
|
_._ o._ o._ 1
|
||||||
|
_._ o._ o._ 1
|
||||||
|
. . . 1
|
||||||
|
_._ o._ o._ 1
|
||||||
|
._ .o .o 1
|
||||||
|
_._ o._ o._ 1
|
||||||
|
_. o. o. 1
|
||||||
|
_._ o._ o._ 1
|
||||||
|
_._ o._ o._ 1
|
||||||
|
. . . 1
|
||||||
|
. . . 1
|
||||||
|
. . . 1
|
||||||
|
._ .oo .oo 1
|
||||||
|
. . . 1
|
||||||
|
_. oo. oo. 1
|
||||||
|
. . . 1
|
||||||
|
_._ oo._ oo._ 1
|
||||||
|
._ .oo .oo 1
|
||||||
|
. . . 1
|
||||||
|
._ .oo .oo 1
|
||||||
|
._ .oo .oo 1
|
||||||
|
._ .oo .oo 1
|
||||||
|
_. oo. oo. 1
|
||||||
|
._ .oo .oo 1
|
||||||
|
_._ oo._ oo._ 1
|
||||||
|
_. oo. oo. 1
|
||||||
|
. . . 1
|
||||||
|
_. oo. oo. 1
|
||||||
|
._ .oo .oo 1
|
||||||
|
_. oo. oo. 1
|
||||||
|
_. oo. oo. 1
|
||||||
|
_. oo. oo. 1
|
||||||
|
_._ oo._ oo._ 1
|
||||||
|
_._ oo._ oo._ 1
|
||||||
|
. . . 1
|
||||||
|
_._ oo._ oo._ 1
|
||||||
|
._ .oo .oo 1
|
||||||
|
_._ oo._ oo._ 1
|
||||||
|
_. oo. oo. 1
|
||||||
|
_._ oo._ oo._ 1
|
||||||
|
_._ oo._ oo._ 1
|
||||||
|
. . . 1
|
||||||
|
. . . 1
|
||||||
|
. . . 1
|
||||||
|
.__ .o_ .o_ 1
|
||||||
|
. . . 1
|
||||||
|
__. o_. o_. 1
|
||||||
|
. . . 1
|
||||||
|
__.__ o_.__ o_.__ 1
|
||||||
|
.__ .o_ .o_ 1
|
||||||
|
. . . 1
|
||||||
|
.__ .o_ .o_ 1
|
||||||
|
.__ .o_ .o_ 1
|
||||||
|
.__ .o_ .o_ 1
|
||||||
|
__. o_. o_. 1
|
||||||
|
.__ .o_ .o_ 1
|
||||||
|
__.__ o_.__ o_.__ 1
|
||||||
|
__. o_. o_. 1
|
||||||
|
. . . 1
|
||||||
|
__. o_. o_. 1
|
||||||
|
.__ .o_ .o_ 1
|
||||||
|
__. o_. o_. 1
|
||||||
|
__. o_. o_. 1
|
||||||
|
__. o_. o_. 1
|
||||||
|
__.__ o_.__ o_.__ 1
|
||||||
|
__.__ o_.__ o_.__ 1
|
||||||
|
. . . 1
|
||||||
|
__.__ o_.__ o_.__ 1
|
||||||
|
.__ .o_ .o_ 1
|
||||||
|
__.__ o_.__ o_.__ 1
|
||||||
|
__. o_. o_. 1
|
||||||
|
__.__ o_.__ o_.__ 1
|
||||||
|
__.__ o_.__ o_.__ 1
|
101
dbms/tests/queries/0_stateless/00240_replace_substring_loop.sql
Normal file
101
dbms/tests/queries/0_stateless/00240_replace_substring_loop.sql
Normal file
@ -0,0 +1,101 @@
|
|||||||
|
SELECT s, replaceAll(s, '_', 'o') AS a, replaceRegexpAll(s, '_', 'o') AS b, a = b FROM (SELECT arrayJoin(['.', '.']) AS s);
|
||||||
|
SELECT s, replaceAll(s, '_', 'o') AS a, replaceRegexpAll(s, '_', 'o') AS b, a = b FROM (SELECT arrayJoin(['.', '._']) AS s);
|
||||||
|
SELECT s, replaceAll(s, '_', 'o') AS a, replaceRegexpAll(s, '_', 'o') AS b, a = b FROM (SELECT arrayJoin(['.', '_.']) AS s);
|
||||||
|
SELECT s, replaceAll(s, '_', 'o') AS a, replaceRegexpAll(s, '_', 'o') AS b, a = b FROM (SELECT arrayJoin(['.', '_._']) AS s);
|
||||||
|
SELECT s, replaceAll(s, '_', 'o') AS a, replaceRegexpAll(s, '_', 'o') AS b, a = b FROM (SELECT arrayJoin(['._', '.']) AS s);
|
||||||
|
SELECT s, replaceAll(s, '_', 'o') AS a, replaceRegexpAll(s, '_', 'o') AS b, a = b FROM (SELECT arrayJoin(['._', '._']) AS s);
|
||||||
|
SELECT s, replaceAll(s, '_', 'o') AS a, replaceRegexpAll(s, '_', 'o') AS b, a = b FROM (SELECT arrayJoin(['._', '_.']) AS s);
|
||||||
|
SELECT s, replaceAll(s, '_', 'o') AS a, replaceRegexpAll(s, '_', 'o') AS b, a = b FROM (SELECT arrayJoin(['._', '_._']) AS s);
|
||||||
|
SELECT s, replaceAll(s, '_', 'o') AS a, replaceRegexpAll(s, '_', 'o') AS b, a = b FROM (SELECT arrayJoin(['_.', '.']) AS s);
|
||||||
|
SELECT s, replaceAll(s, '_', 'o') AS a, replaceRegexpAll(s, '_', 'o') AS b, a = b FROM (SELECT arrayJoin(['_.', '._']) AS s);
|
||||||
|
SELECT s, replaceAll(s, '_', 'o') AS a, replaceRegexpAll(s, '_', 'o') AS b, a = b FROM (SELECT arrayJoin(['_.', '_.']) AS s);
|
||||||
|
SELECT s, replaceAll(s, '_', 'o') AS a, replaceRegexpAll(s, '_', 'o') AS b, a = b FROM (SELECT arrayJoin(['_.', '_._']) AS s);
|
||||||
|
SELECT s, replaceAll(s, '_', 'o') AS a, replaceRegexpAll(s, '_', 'o') AS b, a = b FROM (SELECT arrayJoin(['_._', '.']) AS s);
|
||||||
|
SELECT s, replaceAll(s, '_', 'o') AS a, replaceRegexpAll(s, '_', 'o') AS b, a = b FROM (SELECT arrayJoin(['_._', '._']) AS s);
|
||||||
|
SELECT s, replaceAll(s, '_', 'o') AS a, replaceRegexpAll(s, '_', 'o') AS b, a = b FROM (SELECT arrayJoin(['_._', '_.']) AS s);
|
||||||
|
SELECT s, replaceAll(s, '_', 'o') AS a, replaceRegexpAll(s, '_', 'o') AS b, a = b FROM (SELECT arrayJoin(['_._', '_._']) AS s);
|
||||||
|
|
||||||
|
SELECT s, replaceAll(s, '_', 'oo') AS a, replaceRegexpAll(s, '_', 'oo') AS b, a = b FROM (SELECT arrayJoin(['.', '.']) AS s);
|
||||||
|
SELECT s, replaceAll(s, '_', 'oo') AS a, replaceRegexpAll(s, '_', 'oo') AS b, a = b FROM (SELECT arrayJoin(['.', '._']) AS s);
|
||||||
|
SELECT s, replaceAll(s, '_', 'oo') AS a, replaceRegexpAll(s, '_', 'oo') AS b, a = b FROM (SELECT arrayJoin(['.', '_.']) AS s);
|
||||||
|
SELECT s, replaceAll(s, '_', 'oo') AS a, replaceRegexpAll(s, '_', 'oo') AS b, a = b FROM (SELECT arrayJoin(['.', '_._']) AS s);
|
||||||
|
SELECT s, replaceAll(s, '_', 'oo') AS a, replaceRegexpAll(s, '_', 'oo') AS b, a = b FROM (SELECT arrayJoin(['._', '.']) AS s);
|
||||||
|
SELECT s, replaceAll(s, '_', 'oo') AS a, replaceRegexpAll(s, '_', 'oo') AS b, a = b FROM (SELECT arrayJoin(['._', '._']) AS s);
|
||||||
|
SELECT s, replaceAll(s, '_', 'oo') AS a, replaceRegexpAll(s, '_', 'oo') AS b, a = b FROM (SELECT arrayJoin(['._', '_.']) AS s);
|
||||||
|
SELECT s, replaceAll(s, '_', 'oo') AS a, replaceRegexpAll(s, '_', 'oo') AS b, a = b FROM (SELECT arrayJoin(['._', '_._']) AS s);
|
||||||
|
SELECT s, replaceAll(s, '_', 'oo') AS a, replaceRegexpAll(s, '_', 'oo') AS b, a = b FROM (SELECT arrayJoin(['_.', '.']) AS s);
|
||||||
|
SELECT s, replaceAll(s, '_', 'oo') AS a, replaceRegexpAll(s, '_', 'oo') AS b, a = b FROM (SELECT arrayJoin(['_.', '._']) AS s);
|
||||||
|
SELECT s, replaceAll(s, '_', 'oo') AS a, replaceRegexpAll(s, '_', 'oo') AS b, a = b FROM (SELECT arrayJoin(['_.', '_.']) AS s);
|
||||||
|
SELECT s, replaceAll(s, '_', 'oo') AS a, replaceRegexpAll(s, '_', 'oo') AS b, a = b FROM (SELECT arrayJoin(['_.', '_._']) AS s);
|
||||||
|
SELECT s, replaceAll(s, '_', 'oo') AS a, replaceRegexpAll(s, '_', 'oo') AS b, a = b FROM (SELECT arrayJoin(['_._', '.']) AS s);
|
||||||
|
SELECT s, replaceAll(s, '_', 'oo') AS a, replaceRegexpAll(s, '_', 'oo') AS b, a = b FROM (SELECT arrayJoin(['_._', '._']) AS s);
|
||||||
|
SELECT s, replaceAll(s, '_', 'oo') AS a, replaceRegexpAll(s, '_', 'oo') AS b, a = b FROM (SELECT arrayJoin(['_._', '_.']) AS s);
|
||||||
|
SELECT s, replaceAll(s, '_', 'oo') AS a, replaceRegexpAll(s, '_', 'oo') AS b, a = b FROM (SELECT arrayJoin(['_._', '_._']) AS s);
|
||||||
|
|
||||||
|
SELECT s, replaceAll(s, '_', 'o') AS a, replaceRegexpAll(s, '_', 'o') AS b, a = b FROM (SELECT arrayJoin(['.', '.']) AS s);
|
||||||
|
SELECT s, replaceAll(s, '_', 'o') AS a, replaceRegexpAll(s, '_', 'o') AS b, a = b FROM (SELECT arrayJoin(['.', '.__']) AS s);
|
||||||
|
SELECT s, replaceAll(s, '_', 'o') AS a, replaceRegexpAll(s, '_', 'o') AS b, a = b FROM (SELECT arrayJoin(['.', '__.']) AS s);
|
||||||
|
SELECT s, replaceAll(s, '_', 'o') AS a, replaceRegexpAll(s, '_', 'o') AS b, a = b FROM (SELECT arrayJoin(['.', '__.__']) AS s);
|
||||||
|
SELECT s, replaceAll(s, '_', 'o') AS a, replaceRegexpAll(s, '_', 'o') AS b, a = b FROM (SELECT arrayJoin(['.__', '.']) AS s);
|
||||||
|
SELECT s, replaceAll(s, '_', 'o') AS a, replaceRegexpAll(s, '_', 'o') AS b, a = b FROM (SELECT arrayJoin(['.__', '.__']) AS s);
|
||||||
|
SELECT s, replaceAll(s, '_', 'o') AS a, replaceRegexpAll(s, '_', 'o') AS b, a = b FROM (SELECT arrayJoin(['.__', '__.']) AS s);
|
||||||
|
SELECT s, replaceAll(s, '_', 'o') AS a, replaceRegexpAll(s, '_', 'o') AS b, a = b FROM (SELECT arrayJoin(['.__', '__.__']) AS s);
|
||||||
|
SELECT s, replaceAll(s, '_', 'o') AS a, replaceRegexpAll(s, '_', 'o') AS b, a = b FROM (SELECT arrayJoin(['__.', '.']) AS s);
|
||||||
|
SELECT s, replaceAll(s, '_', 'o') AS a, replaceRegexpAll(s, '_', 'o') AS b, a = b FROM (SELECT arrayJoin(['__.', '.__']) AS s);
|
||||||
|
SELECT s, replaceAll(s, '_', 'o') AS a, replaceRegexpAll(s, '_', 'o') AS b, a = b FROM (SELECT arrayJoin(['__.', '__.']) AS s);
|
||||||
|
SELECT s, replaceAll(s, '_', 'o') AS a, replaceRegexpAll(s, '_', 'o') AS b, a = b FROM (SELECT arrayJoin(['__.', '__.__']) AS s);
|
||||||
|
SELECT s, replaceAll(s, '_', 'o') AS a, replaceRegexpAll(s, '_', 'o') AS b, a = b FROM (SELECT arrayJoin(['__.__', '.']) AS s);
|
||||||
|
SELECT s, replaceAll(s, '_', 'o') AS a, replaceRegexpAll(s, '_', 'o') AS b, a = b FROM (SELECT arrayJoin(['__.__', '.__']) AS s);
|
||||||
|
SELECT s, replaceAll(s, '_', 'o') AS a, replaceRegexpAll(s, '_', 'o') AS b, a = b FROM (SELECT arrayJoin(['__.__', '__.']) AS s);
|
||||||
|
SELECT s, replaceAll(s, '_', 'o') AS a, replaceRegexpAll(s, '_', 'o') AS b, a = b FROM (SELECT arrayJoin(['__.__', '__.__']) AS s);
|
||||||
|
|
||||||
|
SELECT s, replaceOne(s, '_', 'o') AS a, replaceRegexpOne(s, '_', 'o') AS b, a = b FROM (SELECT arrayJoin(['.', '.']) AS s);
|
||||||
|
SELECT s, replaceOne(s, '_', 'o') AS a, replaceRegexpOne(s, '_', 'o') AS b, a = b FROM (SELECT arrayJoin(['.', '._']) AS s);
|
||||||
|
SELECT s, replaceOne(s, '_', 'o') AS a, replaceRegexpOne(s, '_', 'o') AS b, a = b FROM (SELECT arrayJoin(['.', '_.']) AS s);
|
||||||
|
SELECT s, replaceOne(s, '_', 'o') AS a, replaceRegexpOne(s, '_', 'o') AS b, a = b FROM (SELECT arrayJoin(['.', '_._']) AS s);
|
||||||
|
SELECT s, replaceOne(s, '_', 'o') AS a, replaceRegexpOne(s, '_', 'o') AS b, a = b FROM (SELECT arrayJoin(['._', '.']) AS s);
|
||||||
|
SELECT s, replaceOne(s, '_', 'o') AS a, replaceRegexpOne(s, '_', 'o') AS b, a = b FROM (SELECT arrayJoin(['._', '._']) AS s);
|
||||||
|
SELECT s, replaceOne(s, '_', 'o') AS a, replaceRegexpOne(s, '_', 'o') AS b, a = b FROM (SELECT arrayJoin(['._', '_.']) AS s);
|
||||||
|
SELECT s, replaceOne(s, '_', 'o') AS a, replaceRegexpOne(s, '_', 'o') AS b, a = b FROM (SELECT arrayJoin(['._', '_._']) AS s);
|
||||||
|
SELECT s, replaceOne(s, '_', 'o') AS a, replaceRegexpOne(s, '_', 'o') AS b, a = b FROM (SELECT arrayJoin(['_.', '.']) AS s);
|
||||||
|
SELECT s, replaceOne(s, '_', 'o') AS a, replaceRegexpOne(s, '_', 'o') AS b, a = b FROM (SELECT arrayJoin(['_.', '._']) AS s);
|
||||||
|
SELECT s, replaceOne(s, '_', 'o') AS a, replaceRegexpOne(s, '_', 'o') AS b, a = b FROM (SELECT arrayJoin(['_.', '_.']) AS s);
|
||||||
|
SELECT s, replaceOne(s, '_', 'o') AS a, replaceRegexpOne(s, '_', 'o') AS b, a = b FROM (SELECT arrayJoin(['_.', '_._']) AS s);
|
||||||
|
SELECT s, replaceOne(s, '_', 'o') AS a, replaceRegexpOne(s, '_', 'o') AS b, a = b FROM (SELECT arrayJoin(['_._', '.']) AS s);
|
||||||
|
SELECT s, replaceOne(s, '_', 'o') AS a, replaceRegexpOne(s, '_', 'o') AS b, a = b FROM (SELECT arrayJoin(['_._', '._']) AS s);
|
||||||
|
SELECT s, replaceOne(s, '_', 'o') AS a, replaceRegexpOne(s, '_', 'o') AS b, a = b FROM (SELECT arrayJoin(['_._', '_.']) AS s);
|
||||||
|
SELECT s, replaceOne(s, '_', 'o') AS a, replaceRegexpOne(s, '_', 'o') AS b, a = b FROM (SELECT arrayJoin(['_._', '_._']) AS s);
|
||||||
|
|
||||||
|
SELECT s, replaceOne(s, '_', 'oo') AS a, replaceRegexpOne(s, '_', 'oo') AS b, a = b FROM (SELECT arrayJoin(['.', '.']) AS s);
|
||||||
|
SELECT s, replaceOne(s, '_', 'oo') AS a, replaceRegexpOne(s, '_', 'oo') AS b, a = b FROM (SELECT arrayJoin(['.', '._']) AS s);
|
||||||
|
SELECT s, replaceOne(s, '_', 'oo') AS a, replaceRegexpOne(s, '_', 'oo') AS b, a = b FROM (SELECT arrayJoin(['.', '_.']) AS s);
|
||||||
|
SELECT s, replaceOne(s, '_', 'oo') AS a, replaceRegexpOne(s, '_', 'oo') AS b, a = b FROM (SELECT arrayJoin(['.', '_._']) AS s);
|
||||||
|
SELECT s, replaceOne(s, '_', 'oo') AS a, replaceRegexpOne(s, '_', 'oo') AS b, a = b FROM (SELECT arrayJoin(['._', '.']) AS s);
|
||||||
|
SELECT s, replaceOne(s, '_', 'oo') AS a, replaceRegexpOne(s, '_', 'oo') AS b, a = b FROM (SELECT arrayJoin(['._', '._']) AS s);
|
||||||
|
SELECT s, replaceOne(s, '_', 'oo') AS a, replaceRegexpOne(s, '_', 'oo') AS b, a = b FROM (SELECT arrayJoin(['._', '_.']) AS s);
|
||||||
|
SELECT s, replaceOne(s, '_', 'oo') AS a, replaceRegexpOne(s, '_', 'oo') AS b, a = b FROM (SELECT arrayJoin(['._', '_._']) AS s);
|
||||||
|
SELECT s, replaceOne(s, '_', 'oo') AS a, replaceRegexpOne(s, '_', 'oo') AS b, a = b FROM (SELECT arrayJoin(['_.', '.']) AS s);
|
||||||
|
SELECT s, replaceOne(s, '_', 'oo') AS a, replaceRegexpOne(s, '_', 'oo') AS b, a = b FROM (SELECT arrayJoin(['_.', '._']) AS s);
|
||||||
|
SELECT s, replaceOne(s, '_', 'oo') AS a, replaceRegexpOne(s, '_', 'oo') AS b, a = b FROM (SELECT arrayJoin(['_.', '_.']) AS s);
|
||||||
|
SELECT s, replaceOne(s, '_', 'oo') AS a, replaceRegexpOne(s, '_', 'oo') AS b, a = b FROM (SELECT arrayJoin(['_.', '_._']) AS s);
|
||||||
|
SELECT s, replaceOne(s, '_', 'oo') AS a, replaceRegexpOne(s, '_', 'oo') AS b, a = b FROM (SELECT arrayJoin(['_._', '.']) AS s);
|
||||||
|
SELECT s, replaceOne(s, '_', 'oo') AS a, replaceRegexpOne(s, '_', 'oo') AS b, a = b FROM (SELECT arrayJoin(['_._', '._']) AS s);
|
||||||
|
SELECT s, replaceOne(s, '_', 'oo') AS a, replaceRegexpOne(s, '_', 'oo') AS b, a = b FROM (SELECT arrayJoin(['_._', '_.']) AS s);
|
||||||
|
SELECT s, replaceOne(s, '_', 'oo') AS a, replaceRegexpOne(s, '_', 'oo') AS b, a = b FROM (SELECT arrayJoin(['_._', '_._']) AS s);
|
||||||
|
|
||||||
|
SELECT s, replaceOne(s, '_', 'o') AS a, replaceRegexpOne(s, '_', 'o') AS b, a = b FROM (SELECT arrayJoin(['.', '.']) AS s);
|
||||||
|
SELECT s, replaceOne(s, '_', 'o') AS a, replaceRegexpOne(s, '_', 'o') AS b, a = b FROM (SELECT arrayJoin(['.', '.__']) AS s);
|
||||||
|
SELECT s, replaceOne(s, '_', 'o') AS a, replaceRegexpOne(s, '_', 'o') AS b, a = b FROM (SELECT arrayJoin(['.', '__.']) AS s);
|
||||||
|
SELECT s, replaceOne(s, '_', 'o') AS a, replaceRegexpOne(s, '_', 'o') AS b, a = b FROM (SELECT arrayJoin(['.', '__.__']) AS s);
|
||||||
|
SELECT s, replaceOne(s, '_', 'o') AS a, replaceRegexpOne(s, '_', 'o') AS b, a = b FROM (SELECT arrayJoin(['.__', '.']) AS s);
|
||||||
|
SELECT s, replaceOne(s, '_', 'o') AS a, replaceRegexpOne(s, '_', 'o') AS b, a = b FROM (SELECT arrayJoin(['.__', '.__']) AS s);
|
||||||
|
SELECT s, replaceOne(s, '_', 'o') AS a, replaceRegexpOne(s, '_', 'o') AS b, a = b FROM (SELECT arrayJoin(['.__', '__.']) AS s);
|
||||||
|
SELECT s, replaceOne(s, '_', 'o') AS a, replaceRegexpOne(s, '_', 'o') AS b, a = b FROM (SELECT arrayJoin(['.__', '__.__']) AS s);
|
||||||
|
SELECT s, replaceOne(s, '_', 'o') AS a, replaceRegexpOne(s, '_', 'o') AS b, a = b FROM (SELECT arrayJoin(['__.', '.']) AS s);
|
||||||
|
SELECT s, replaceOne(s, '_', 'o') AS a, replaceRegexpOne(s, '_', 'o') AS b, a = b FROM (SELECT arrayJoin(['__.', '.__']) AS s);
|
||||||
|
SELECT s, replaceOne(s, '_', 'o') AS a, replaceRegexpOne(s, '_', 'o') AS b, a = b FROM (SELECT arrayJoin(['__.', '__.']) AS s);
|
||||||
|
SELECT s, replaceOne(s, '_', 'o') AS a, replaceRegexpOne(s, '_', 'o') AS b, a = b FROM (SELECT arrayJoin(['__.', '__.__']) AS s);
|
||||||
|
SELECT s, replaceOne(s, '_', 'o') AS a, replaceRegexpOne(s, '_', 'o') AS b, a = b FROM (SELECT arrayJoin(['__.__', '.']) AS s);
|
||||||
|
SELECT s, replaceOne(s, '_', 'o') AS a, replaceRegexpOne(s, '_', 'o') AS b, a = b FROM (SELECT arrayJoin(['__.__', '.__']) AS s);
|
||||||
|
SELECT s, replaceOne(s, '_', 'o') AS a, replaceRegexpOne(s, '_', 'o') AS b, a = b FROM (SELECT arrayJoin(['__.__', '__.']) AS s);
|
||||||
|
SELECT s, replaceOne(s, '_', 'o') AS a, replaceRegexpOne(s, '_', 'o') AS b, a = b FROM (SELECT arrayJoin(['__.__', '__.__']) AS s);
|
@ -0,0 +1,15 @@
|
|||||||
|
1 0 0 0 1 1
|
||||||
|
0 1 1 0 1 0
|
||||||
|
0 1 1 0 1 0
|
||||||
|
0 1 1 0 1 0
|
||||||
|
0 1 0 1 0 1
|
||||||
|
0 1 0 1 0 1
|
||||||
|
0 1 0 1 0 1
|
||||||
|
1 0 0 0 1 1
|
||||||
|
0 1 1 0 1 0
|
||||||
|
0 1 1 0 1 0
|
||||||
|
0 1 0 1 0 1
|
||||||
|
0 1 0 1 0 1
|
||||||
|
1 0 0 0 1 1
|
||||||
|
0 1 1 0 1 0
|
||||||
|
0 1 0 1 0 1
|
105
dbms/tests/queries/0_stateless/00250_tuple_comparison.sql
Normal file
105
dbms/tests/queries/0_stateless/00250_tuple_comparison.sql
Normal file
@ -0,0 +1,105 @@
|
|||||||
|
SELECT
|
||||||
|
(1, 'Hello', 23) = (1, 'Hello', 23),
|
||||||
|
(1, 'Hello', 23) != (1, 'Hello', 23),
|
||||||
|
(1, 'Hello', 23) < (1, 'Hello', 23),
|
||||||
|
(1, 'Hello', 23) > (1, 'Hello', 23),
|
||||||
|
(1, 'Hello', 23) <= (1, 'Hello', 23),
|
||||||
|
(1, 'Hello', 23) >= (1, 'Hello', 23);
|
||||||
|
SELECT
|
||||||
|
(1, 'Hello', 23) = (2, 'Hello', 23),
|
||||||
|
(1, 'Hello', 23) != (2, 'Hello', 23),
|
||||||
|
(1, 'Hello', 23) < (2, 'Hello', 23),
|
||||||
|
(1, 'Hello', 23) > (2, 'Hello', 23),
|
||||||
|
(1, 'Hello', 23) <= (2, 'Hello', 23),
|
||||||
|
(1, 'Hello', 23) >= (2, 'Hello', 23);
|
||||||
|
SELECT
|
||||||
|
(1, 'Hello', 23) = (1, 'World', 23),
|
||||||
|
(1, 'Hello', 23) != (1, 'World', 23),
|
||||||
|
(1, 'Hello', 23) < (1, 'World', 23),
|
||||||
|
(1, 'Hello', 23) > (1, 'World', 23),
|
||||||
|
(1, 'Hello', 23) <= (1, 'World', 23),
|
||||||
|
(1, 'Hello', 23) >= (1, 'World', 23);
|
||||||
|
SELECT
|
||||||
|
(1, 'Hello', 23) = (1, 'Hello', 24),
|
||||||
|
(1, 'Hello', 23) != (1, 'Hello', 24),
|
||||||
|
(1, 'Hello', 23) < (1, 'Hello', 24),
|
||||||
|
(1, 'Hello', 23) > (1, 'Hello', 24),
|
||||||
|
(1, 'Hello', 23) <= (1, 'Hello', 24),
|
||||||
|
(1, 'Hello', 23) >= (1, 'Hello', 24);
|
||||||
|
SELECT
|
||||||
|
(2, 'Hello', 23) = (1, 'Hello', 23),
|
||||||
|
(2, 'Hello', 23) != (1, 'Hello', 23),
|
||||||
|
(2, 'Hello', 23) < (1, 'Hello', 23),
|
||||||
|
(2, 'Hello', 23) > (1, 'Hello', 23),
|
||||||
|
(2, 'Hello', 23) <= (1, 'Hello', 23),
|
||||||
|
(2, 'Hello', 23) >= (1, 'Hello', 23);
|
||||||
|
SELECT
|
||||||
|
(1, 'World', 23) = (1, 'Hello', 23),
|
||||||
|
(1, 'World', 23) != (1, 'Hello', 23),
|
||||||
|
(1, 'World', 23) < (1, 'Hello', 23),
|
||||||
|
(1, 'World', 23) > (1, 'Hello', 23),
|
||||||
|
(1, 'World', 23) <= (1, 'Hello', 23),
|
||||||
|
(1, 'World', 23) >= (1, 'Hello', 23);
|
||||||
|
SELECT
|
||||||
|
(1, 'Hello', 24) = (1, 'Hello', 23),
|
||||||
|
(1, 'Hello', 24) != (1, 'Hello', 23),
|
||||||
|
(1, 'Hello', 24) < (1, 'Hello', 23),
|
||||||
|
(1, 'Hello', 24) > (1, 'Hello', 23),
|
||||||
|
(1, 'Hello', 24) <= (1, 'Hello', 23),
|
||||||
|
(1, 'Hello', 24) >= (1, 'Hello', 23);
|
||||||
|
SELECT
|
||||||
|
(1, 'Hello') = (1, 'Hello'),
|
||||||
|
(1, 'Hello') != (1, 'Hello'),
|
||||||
|
(1, 'Hello') < (1, 'Hello'),
|
||||||
|
(1, 'Hello') > (1, 'Hello'),
|
||||||
|
(1, 'Hello') <= (1, 'Hello'),
|
||||||
|
(1, 'Hello') >= (1, 'Hello');
|
||||||
|
SELECT
|
||||||
|
(1, 'Hello') = (2, 'Hello'),
|
||||||
|
(1, 'Hello') != (2, 'Hello'),
|
||||||
|
(1, 'Hello') < (2, 'Hello'),
|
||||||
|
(1, 'Hello') > (2, 'Hello'),
|
||||||
|
(1, 'Hello') <= (2, 'Hello'),
|
||||||
|
(1, 'Hello') >= (2, 'Hello');
|
||||||
|
SELECT
|
||||||
|
(1, 'Hello') = (1, 'World'),
|
||||||
|
(1, 'Hello') != (1, 'World'),
|
||||||
|
(1, 'Hello') < (1, 'World'),
|
||||||
|
(1, 'Hello') > (1, 'World'),
|
||||||
|
(1, 'Hello') <= (1, 'World'),
|
||||||
|
(1, 'Hello') >= (1, 'World');
|
||||||
|
SELECT
|
||||||
|
(2, 'Hello') = (1, 'Hello'),
|
||||||
|
(2, 'Hello') != (1, 'Hello'),
|
||||||
|
(2, 'Hello') < (1, 'Hello'),
|
||||||
|
(2, 'Hello') > (1, 'Hello'),
|
||||||
|
(2, 'Hello') <= (1, 'Hello'),
|
||||||
|
(2, 'Hello') >= (1, 'Hello');
|
||||||
|
SELECT
|
||||||
|
(1, 'World') = (1, 'Hello'),
|
||||||
|
(1, 'World') != (1, 'Hello'),
|
||||||
|
(1, 'World') < (1, 'Hello'),
|
||||||
|
(1, 'World') > (1, 'Hello'),
|
||||||
|
(1, 'World') <= (1, 'Hello'),
|
||||||
|
(1, 'World') >= (1, 'Hello');
|
||||||
|
SELECT
|
||||||
|
tuple(1) = tuple(1),
|
||||||
|
tuple(1) != tuple(1),
|
||||||
|
tuple(1) < tuple(1),
|
||||||
|
tuple(1) > tuple(1),
|
||||||
|
tuple(1) <= tuple(1),
|
||||||
|
tuple(1) >= tuple(1);
|
||||||
|
SELECT
|
||||||
|
tuple(1) = tuple(2),
|
||||||
|
tuple(1) != tuple(2),
|
||||||
|
tuple(1) < tuple(2),
|
||||||
|
tuple(1) > tuple(2),
|
||||||
|
tuple(1) <= tuple(2),
|
||||||
|
tuple(1) >= tuple(2);
|
||||||
|
SELECT
|
||||||
|
tuple(2) = tuple(1),
|
||||||
|
tuple(2) != tuple(1),
|
||||||
|
tuple(2) < tuple(1),
|
||||||
|
tuple(2) > tuple(1),
|
||||||
|
tuple(2) <= tuple(1),
|
||||||
|
tuple(2) >= tuple(1);
|
20
dbms/tests/queries/0_stateless/00251_has_types.reference
Normal file
20
dbms/tests/queries/0_stateless/00251_has_types.reference
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
1
|
||||||
|
1
|
||||||
|
0
|
||||||
|
1
|
||||||
|
0
|
||||||
|
1
|
||||||
|
1
|
||||||
|
0
|
||||||
|
1
|
||||||
|
0
|
||||||
|
1
|
||||||
|
1
|
||||||
|
0
|
||||||
|
1
|
||||||
|
0
|
||||||
|
1
|
||||||
|
1
|
||||||
|
0
|
||||||
|
1
|
||||||
|
0
|
23
dbms/tests/queries/0_stateless/00251_has_types.sql
Normal file
23
dbms/tests/queries/0_stateless/00251_has_types.sql
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
SELECT has([1, 2, 3], 3.0);
|
||||||
|
SELECT has([1, 2.0, 3], 2);
|
||||||
|
SELECT has([1, 2.1, 3], 2);
|
||||||
|
SELECT has([1, -1], 1);
|
||||||
|
SELECT has([1, -1], 1000);
|
||||||
|
|
||||||
|
SELECT has(materialize([1, 2, 3]), 3.0);
|
||||||
|
SELECT has(materialize([1, 2.0, 3]), 2);
|
||||||
|
SELECT has(materialize([1, 2.1, 3]), 2);
|
||||||
|
SELECT has(materialize([1, -1]), 1);
|
||||||
|
SELECT has(materialize([1, -1]), 1000);
|
||||||
|
|
||||||
|
SELECT has([1, 2, 3], materialize(3.0));
|
||||||
|
SELECT has([1, 2.0, 3], materialize(2));
|
||||||
|
SELECT has([1, 2.1, 3], materialize(2));
|
||||||
|
SELECT has([1, -1], materialize(1));
|
||||||
|
SELECT has([1, -1], materialize(1000));
|
||||||
|
|
||||||
|
SELECT has(materialize([1, 2, 3]), materialize(3.0));
|
||||||
|
SELECT has(materialize([1, 2.0, 3]), materialize(2));
|
||||||
|
SELECT has(materialize([1, 2.1, 3]), materialize(2));
|
||||||
|
SELECT has(materialize([1, -1]), materialize(1));
|
||||||
|
SELECT has(materialize([1, -1]), materialize(1000));
|
Loading…
Reference in New Issue
Block a user