Added support for non-constant and negative offset and size for substring function (continued) [#CLICKHOUSE-2].

This commit is contained in:
Alexey Milovidov 2017-07-24 10:48:26 +03:00 committed by alexey-milovidov
parent 487278e2f5
commit a6df2e7151
5 changed files with 54 additions and 31 deletions

View File

@ -107,6 +107,11 @@ public:
return data->get64(0);
}
UInt64 getUInt(size_t n) const override
{
return data->getUInt(0);
}
Int64 getInt(size_t n) const override
{
return data->getInt(0);

View File

@ -221,6 +221,11 @@ public:
UInt64 get64(size_t n) const override;
UInt64 getUInt(size_t n) const override
{
return UInt64(data[n]);
}
Int64 getInt(size_t n) const override
{
return Int64(data[n]);

View File

@ -111,9 +111,14 @@ public:
throw Exception("Method get64 is not supported for " + getName(), ErrorCodes::NOT_IMPLEMENTED);
}
/** If column is numeric, return value of n-th element, casted to Int64.
/** If column is numeric, return value of n-th element, casted to UInt64.
* Otherwise throw an exception.
*/
virtual UInt64 getUInt(size_t n) const
{
throw Exception("Method getUInt is not supported for " + getName(), ErrorCodes::NOT_IMPLEMENTED);
}
virtual Int64 getInt(size_t n) const
{
throw Exception("Method getInt is not supported for " + getName(), ErrorCodes::NOT_IMPLEMENTED);

View File

@ -50,13 +50,13 @@ struct UInt128
template <typename T> bool inline operator<= (const T rhs) const { return *this <= UInt128(rhs); }
template <typename T> bool inline operator< (const T rhs) const { return *this < UInt128(rhs); }
template<typename T> explicit operator T() const { return static_cast<T>(high); }
template<typename T> explicit operator T() const { return static_cast<T>(low); }
#if !__clang__
#pragma GCC diagnostic pop
#endif
UInt128 & operator= (const UInt64 rhs) { low = 0; high = rhs; return *this; }
UInt128 & operator= (const UInt64 rhs) { low = rhs; high = 0; return *this; }
};
template <typename T> bool inline operator== (T a, const UInt128 b) { return UInt128(a) == b; }

View File

@ -718,37 +718,45 @@ private:
const ColumnString * c1_string = checkAndGetColumn<ColumnString>(c1);
const ColumnFixedString * c0_fixed_string = checkAndGetColumn<ColumnFixedString>(c0);
const ColumnFixedString * c1_fixed_string = checkAndGetColumn<ColumnFixedString>(c1);
const ColumnConst * c0_const = checkAndGetColumnConstStringOrFixedString(c0);
const ColumnConst * c1_const = checkAndGetColumnConstStringOrFixedString(c1);
const ColumnConst * c0_const_string = checkAndGetColumnConst<ColumnString>(c0);
const ColumnConst * c1_const_string = checkAndGetColumnConst<ColumnString>(c1);
const ColumnConst * c0_const_fixed_string = checkAndGetColumnConst<ColumnFixedString>(c0);
const ColumnConst * c1_const_fixed_string = checkAndGetColumnConst<ColumnFixedString>(c1);
{
auto c_res = std::make_shared<ColumnString>();
auto c_res = std::make_shared<ColumnString>();
if (c0_string && c1_string)
concat(StringSource(*c0_string), StringSource(*c1_string), StringSink(*c_res, c0->size()));
else if (c0_string && c1_fixed_string)
concat(StringSource(*c0_string), FixedStringSource(*c1_fixed_string), StringSink(*c_res, c0->size()));
else if (c0_string && c1_const)
concat(StringSource(*c0_string), ConstSource<StringSource>(*c1_const), StringSink(*c_res, c0->size()));
else if (c0_fixed_string && c1_string)
concat(FixedStringSource(*c0_fixed_string), StringSource(*c1_string), StringSink(*c_res, c0->size()));
else if (c0_const && c1_string)
concat(ConstSource<StringSource>(*c0_const), StringSource(*c1_string), StringSink(*c_res, c0->size()));
else if (c0_fixed_string && c1_fixed_string)
concat(FixedStringSource(*c0_fixed_string), FixedStringSource(*c1_fixed_string), StringSink(*c_res, c0->size()));
else if (c0_fixed_string && c1_const)
concat(FixedStringSource(*c0_fixed_string), ConstSource<StringSource>(*c1_const), StringSink(*c_res, c0->size()));
else if (c0_const && c1_fixed_string)
concat(ConstSource<StringSource>(*c0_const), FixedStringSource(*c1_fixed_string), StringSink(*c_res, c0->size()));
else
throw Exception("Illegal columns " + block.getByPosition(arguments[0]).column->getName() + " and "
+ block.getByPosition(arguments[1]).column->getName()
+ " of arguments of function "
+ getName(),
ErrorCodes::ILLEGAL_COLUMN);
if (c0_string && c1_string)
concat(StringSource(*c0_string), StringSource(*c1_string), StringSink(*c_res, c0->size()));
else if (c0_string && c1_fixed_string)
concat(StringSource(*c0_string), FixedStringSource(*c1_fixed_string), StringSink(*c_res, c0->size()));
else if (c0_string && c1_const_string)
concat(StringSource(*c0_string), ConstSource<StringSource>(*c1_const_string), StringSink(*c_res, c0->size()));
else if (c0_string && c1_const_fixed_string)
concat(StringSource(*c0_string), ConstSource<FixedStringSource>(*c1_const_fixed_string), StringSink(*c_res, c0->size()));
else if (c0_fixed_string && c1_string)
concat(FixedStringSource(*c0_fixed_string), StringSource(*c1_string), StringSink(*c_res, c0->size()));
else if (c0_const_string && c1_string)
concat(ConstSource<StringSource>(*c0_const_string), StringSource(*c1_string), StringSink(*c_res, c0->size()));
else if (c0_const_fixed_string && c1_string)
concat(ConstSource<FixedStringSource>(*c0_const_fixed_string), StringSource(*c1_string), StringSink(*c_res, c0->size()));
else if (c0_fixed_string && c1_fixed_string)
concat(FixedStringSource(*c0_fixed_string), FixedStringSource(*c1_fixed_string), StringSink(*c_res, c0->size()));
else if (c0_fixed_string && c1_const_string)
concat(FixedStringSource(*c0_fixed_string), ConstSource<StringSource>(*c1_const_string), StringSink(*c_res, c0->size()));
else if (c0_fixed_string && c1_const_fixed_string)
concat(FixedStringSource(*c0_fixed_string), ConstSource<FixedStringSource>(*c1_const_fixed_string), StringSink(*c_res, c0->size()));
else if (c0_const_string && c1_fixed_string)
concat(ConstSource<StringSource>(*c0_const_string), FixedStringSource(*c1_fixed_string), StringSink(*c_res, c0->size()));
else if (c0_const_fixed_string && c1_fixed_string)
concat(ConstSource<FixedStringSource>(*c0_const_fixed_string), FixedStringSource(*c1_fixed_string), StringSink(*c_res, c0->size()));
else
throw Exception("Illegal columns " + block.getByPosition(arguments[0]).column->getName() + " and "
+ block.getByPosition(arguments[1]).column->getName()
+ " of arguments of function "
+ getName(),
ErrorCodes::ILLEGAL_COLUMN);
block.getByPosition(result).column = c_res;
}
block.getByPosition(result).column = c_res;
}
void executeNAry(Block & block, const ColumnNumbers & arguments, const size_t result)