mirror of
https://github.com/ClickHouse/ClickHouse.git
synced 2024-11-24 08:32:02 +00:00
Add function bitSlice for String and FixedString
This commit is contained in:
parent
b29e8688a5
commit
f2e5399c61
480
src/Functions/bitSlice.cpp
Normal file
480
src/Functions/bitSlice.cpp
Normal file
@ -0,0 +1,480 @@
|
|||||||
|
#include <Columns/ColumnConst.h>
|
||||||
|
#include <Columns/ColumnFixedString.h>
|
||||||
|
#include <Columns/ColumnString.h>
|
||||||
|
#include <DataTypes/DataTypeString.h>
|
||||||
|
#include <Functions/FunctionFactory.h>
|
||||||
|
#include <Functions/FunctionHelpers.h>
|
||||||
|
#include <Functions/GatherUtils/Algorithms.h>
|
||||||
|
#include <Functions/GatherUtils/GatherUtils.h>
|
||||||
|
#include <Functions/GatherUtils/Sinks.h>
|
||||||
|
#include <Functions/GatherUtils/Slices.h>
|
||||||
|
#include <Functions/GatherUtils/Sources.h>
|
||||||
|
#include <Functions/IFunction.h>
|
||||||
|
#include <IO/WriteHelpers.h>
|
||||||
|
|
||||||
|
namespace DB
|
||||||
|
{
|
||||||
|
using namespace GatherUtils;
|
||||||
|
|
||||||
|
namespace ErrorCodes
|
||||||
|
{
|
||||||
|
extern const int ILLEGAL_COLUMN;
|
||||||
|
extern const int ILLEGAL_TYPE_OF_ARGUMENT;
|
||||||
|
extern const int ZERO_ARRAY_OR_TUPLE_INDEX;
|
||||||
|
extern const int NUMBER_OF_ARGUMENTS_DOESNT_MATCH;
|
||||||
|
}
|
||||||
|
|
||||||
|
class FunctionBitSlice : public IFunction
|
||||||
|
{
|
||||||
|
const UInt8 word_size = 8;
|
||||||
|
|
||||||
|
public:
|
||||||
|
static constexpr auto name = "bitSlice";
|
||||||
|
static FunctionPtr create(ContextPtr) { return std::make_shared<FunctionBitSlice>(); }
|
||||||
|
|
||||||
|
String getName() const override { return name; }
|
||||||
|
|
||||||
|
bool isVariadic() const override { return true; }
|
||||||
|
size_t getNumberOfArguments() const override { return 0; }
|
||||||
|
|
||||||
|
bool isSuitableForShortCircuitArgumentsExecution(const DataTypesWithConstInfo & /*arguments*/) const override { return true; }
|
||||||
|
|
||||||
|
DataTypePtr getReturnTypeImpl(const DataTypes & arguments) const override
|
||||||
|
{
|
||||||
|
const size_t number_of_arguments = arguments.size();
|
||||||
|
|
||||||
|
if (number_of_arguments < 2 || number_of_arguments > 3)
|
||||||
|
throw Exception(
|
||||||
|
"Number of arguments for function " + getName() + " doesn't match: passed " + toString(number_of_arguments)
|
||||||
|
+ ", should be 2 or 3",
|
||||||
|
ErrorCodes::NUMBER_OF_ARGUMENTS_DOESNT_MATCH);
|
||||||
|
|
||||||
|
if (!isString(arguments[0]) && !isStringOrFixedString(arguments[0]))
|
||||||
|
throw Exception(
|
||||||
|
"Illegal type " + arguments[0]->getName() + " of argument of function " + getName(), ErrorCodes::ILLEGAL_TYPE_OF_ARGUMENT);
|
||||||
|
if (arguments[0]->onlyNull())
|
||||||
|
return arguments[0];
|
||||||
|
|
||||||
|
if (!isNativeNumber(arguments[1]))
|
||||||
|
throw Exception(
|
||||||
|
"Illegal type " + arguments[1]->getName() + " of second argument of function " + getName(),
|
||||||
|
ErrorCodes::ILLEGAL_TYPE_OF_ARGUMENT);
|
||||||
|
|
||||||
|
if (number_of_arguments == 3 && !isNativeNumber(arguments[2]))
|
||||||
|
throw Exception(
|
||||||
|
"Illegal type " + arguments[2]->getName() + " of second argument of function " + getName(),
|
||||||
|
ErrorCodes::ILLEGAL_TYPE_OF_ARGUMENT);
|
||||||
|
|
||||||
|
return std::make_shared<DataTypeString>();
|
||||||
|
}
|
||||||
|
|
||||||
|
ColumnPtr executeImpl(const ColumnsWithTypeAndName & arguments, const DataTypePtr &, size_t input_rows_count) const override
|
||||||
|
{
|
||||||
|
size_t number_of_arguments = arguments.size();
|
||||||
|
|
||||||
|
ColumnPtr column_string = arguments[0].column;
|
||||||
|
ColumnPtr column_start = arguments[1].column;
|
||||||
|
ColumnPtr column_length;
|
||||||
|
|
||||||
|
if (number_of_arguments == 3)
|
||||||
|
column_length = arguments[2].column;
|
||||||
|
|
||||||
|
const ColumnConst * column_start_const = checkAndGetColumn<ColumnConst>(column_start.get());
|
||||||
|
const ColumnConst * column_length_const = nullptr;
|
||||||
|
|
||||||
|
if (number_of_arguments == 3)
|
||||||
|
column_length_const = checkAndGetColumn<ColumnConst>(column_length.get());
|
||||||
|
|
||||||
|
Int64 start_value = 0;
|
||||||
|
Int64 length_value = 0;
|
||||||
|
|
||||||
|
if (column_start_const)
|
||||||
|
start_value = column_start_const->getInt(0);
|
||||||
|
if (column_length_const)
|
||||||
|
length_value = column_length_const->getInt(0);
|
||||||
|
|
||||||
|
|
||||||
|
if (const ColumnString * col = checkAndGetColumn<ColumnString>(column_string.get()))
|
||||||
|
return executeForSource(
|
||||||
|
column_start,
|
||||||
|
column_length,
|
||||||
|
column_start_const,
|
||||||
|
column_length_const,
|
||||||
|
start_value,
|
||||||
|
length_value,
|
||||||
|
StringSource(*col),
|
||||||
|
input_rows_count);
|
||||||
|
else if (const ColumnFixedString * col_fixed = checkAndGetColumn<ColumnFixedString>(column_string.get()))
|
||||||
|
return executeForSource(
|
||||||
|
column_start,
|
||||||
|
column_length,
|
||||||
|
column_start_const,
|
||||||
|
column_length_const,
|
||||||
|
start_value,
|
||||||
|
length_value,
|
||||||
|
FixedStringSource(*col_fixed),
|
||||||
|
input_rows_count);
|
||||||
|
else if (const ColumnConst * col_const = checkAndGetColumnConst<ColumnString>(column_string.get()))
|
||||||
|
return executeForSource(
|
||||||
|
column_start,
|
||||||
|
column_length,
|
||||||
|
column_start_const,
|
||||||
|
column_length_const,
|
||||||
|
start_value,
|
||||||
|
length_value,
|
||||||
|
ConstSource<StringSource>(*col_const),
|
||||||
|
input_rows_count);
|
||||||
|
else if (const ColumnConst * col_const_fixed = checkAndGetColumnConst<ColumnFixedString>(column_string.get()))
|
||||||
|
return executeForSource(
|
||||||
|
column_start,
|
||||||
|
column_length,
|
||||||
|
column_start_const,
|
||||||
|
column_length_const,
|
||||||
|
start_value,
|
||||||
|
length_value,
|
||||||
|
ConstSource<FixedStringSource>(*col_const_fixed),
|
||||||
|
input_rows_count);
|
||||||
|
else
|
||||||
|
throw Exception(
|
||||||
|
"Illegal column " + arguments[0].column->getName() + " of first argument of function " + getName(),
|
||||||
|
ErrorCodes::ILLEGAL_COLUMN);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class Source>
|
||||||
|
ColumnPtr executeForSource(
|
||||||
|
const ColumnPtr & column_start,
|
||||||
|
const ColumnPtr & column_length,
|
||||||
|
const ColumnConst * column_start_const,
|
||||||
|
const ColumnConst * column_length_const,
|
||||||
|
Int64 start_value,
|
||||||
|
Int64 length_value,
|
||||||
|
Source && source,
|
||||||
|
size_t input_rows_count) const
|
||||||
|
{
|
||||||
|
auto col_res = ColumnString::create();
|
||||||
|
|
||||||
|
if (!column_length)
|
||||||
|
{
|
||||||
|
if (column_start_const)
|
||||||
|
{
|
||||||
|
if (start_value > 0)
|
||||||
|
bitSliceFromLeftConstantOffsetUnbounded(
|
||||||
|
source, StringSink(*col_res, input_rows_count), static_cast<size_t>(start_value - 1));
|
||||||
|
else if (start_value < 0)
|
||||||
|
bitSliceFromRightConstantOffsetUnbounded(
|
||||||
|
source, StringSink(*col_res, input_rows_count), -static_cast<size_t>(start_value));
|
||||||
|
else
|
||||||
|
throw Exception("Indices in strings are 1-based", ErrorCodes::ZERO_ARRAY_OR_TUPLE_INDEX);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
bitSliceDynamicOffsetUnbounded(source, StringSink(*col_res, input_rows_count), *column_start);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (column_start_const && column_length_const)
|
||||||
|
{
|
||||||
|
if (start_value > 0)
|
||||||
|
bitSliceFromLeftConstantOffsetBounded(
|
||||||
|
source, StringSink(*col_res, input_rows_count), static_cast<size_t>(start_value - 1), length_value);
|
||||||
|
else if (start_value < 0)
|
||||||
|
bitSliceFromRightConstantOffsetBounded(
|
||||||
|
source, StringSink(*col_res, input_rows_count), -static_cast<size_t>(start_value), length_value);
|
||||||
|
else
|
||||||
|
throw Exception("Indices in strings are 1-based", ErrorCodes::ZERO_ARRAY_OR_TUPLE_INDEX);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
bitSliceDynamicOffsetBounded(source, StringSink(*col_res, input_rows_count), *column_start, *column_length);
|
||||||
|
}
|
||||||
|
|
||||||
|
return col_res;
|
||||||
|
}
|
||||||
|
|
||||||
|
void writeSliceWithLeftShift(const StringSource::Slice & slice, StringSink & sink, size_t shift_bit, size_t abandon_last_bit = 0) const
|
||||||
|
{
|
||||||
|
if (!shift_bit && !abandon_last_bit)
|
||||||
|
{
|
||||||
|
writeSlice(slice, sink);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
size_t size = slice.size;
|
||||||
|
if (!size)
|
||||||
|
return;
|
||||||
|
bool abandon_last_byte = abandon_last_bit + shift_bit >= word_size;
|
||||||
|
if (abandon_last_byte)
|
||||||
|
size--;
|
||||||
|
sink.elements.resize(sink.current_offset + size);
|
||||||
|
UInt8 * out = &sink.elements[sink.current_offset];
|
||||||
|
const UInt8 * input = slice.data;
|
||||||
|
|
||||||
|
for (size_t i = 0; i < size - 1; i++)
|
||||||
|
{
|
||||||
|
out[i] = (input[i] << shift_bit) | (input[i + 1] >> (word_size - shift_bit));
|
||||||
|
}
|
||||||
|
if (abandon_last_byte)
|
||||||
|
{
|
||||||
|
out[size - 1] = (input[size - 1] << shift_bit) | (input[size] >> (word_size - shift_bit));
|
||||||
|
out[size - 1] = out[size - 1] & (0xFF << (abandon_last_bit + shift_bit - word_size));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
out[size - 1] = (input[size - 1] << shift_bit) & (0xFF << (abandon_last_bit + shift_bit));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
sink.current_offset += size;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template <class Source>
|
||||||
|
void bitSliceFromLeftConstantOffsetUnbounded(Source && src, StringSink && sink, size_t offset) const
|
||||||
|
{
|
||||||
|
size_t offset_byte = offset / word_size;
|
||||||
|
size_t offset_bit = offset % word_size;
|
||||||
|
while (!src.isEnd())
|
||||||
|
{
|
||||||
|
auto sl = src.getSliceFromLeft(offset_byte);
|
||||||
|
if (sl.size)
|
||||||
|
writeSliceWithLeftShift(sl, sink, offset_bit);
|
||||||
|
|
||||||
|
sink.next();
|
||||||
|
src.next();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class Source>
|
||||||
|
void bitSliceFromRightConstantOffsetUnbounded(Source && src, StringSink && sink, size_t offset) const
|
||||||
|
{
|
||||||
|
size_t offset_byte = offset / word_size;
|
||||||
|
size_t offset_bit = (word_size - (offset % word_size)) % word_size;
|
||||||
|
if (offset_bit)
|
||||||
|
offset_byte++;
|
||||||
|
while (!src.isEnd())
|
||||||
|
{
|
||||||
|
auto slice = src.getSliceFromRight(offset_byte);
|
||||||
|
size_t size = src.getElementSize();
|
||||||
|
bool left_truncate = offset_byte > size;
|
||||||
|
size_t shift_bit = left_truncate ? 0 : offset_bit;
|
||||||
|
if (slice.size)
|
||||||
|
writeSliceWithLeftShift(slice, sink, shift_bit);
|
||||||
|
|
||||||
|
sink.next();
|
||||||
|
src.next();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class Source>
|
||||||
|
void bitSliceDynamicOffsetUnbounded(Source && src, StringSink && sink, const IColumn & offset_column) const
|
||||||
|
{
|
||||||
|
const bool is_null = offset_column.onlyNull();
|
||||||
|
const auto * nullable = typeid_cast<const ColumnNullable *>(&offset_column);
|
||||||
|
const ColumnUInt8::Container * null_map = nullable ? &nullable->getNullMapData() : nullptr;
|
||||||
|
const IColumn * nested_column = nullable ? &nullable->getNestedColumn() : &offset_column;
|
||||||
|
|
||||||
|
while (!src.isEnd())
|
||||||
|
{
|
||||||
|
auto row_num = src.rowNum();
|
||||||
|
bool has_offset = !is_null && (null_map && (*null_map)[row_num]);
|
||||||
|
Int64 start = has_offset ? nested_column->getInt(row_num) : 1;
|
||||||
|
if (start != 0)
|
||||||
|
{
|
||||||
|
typename std::decay_t<Source>::Slice slice;
|
||||||
|
size_t shift_bit;
|
||||||
|
|
||||||
|
if (start > 0)
|
||||||
|
{
|
||||||
|
UInt64 offset = start - 1;
|
||||||
|
size_t offset_byte = offset / word_size;
|
||||||
|
size_t offset_bit = offset % word_size;
|
||||||
|
shift_bit = offset_bit;
|
||||||
|
slice = src.getSliceFromLeft(offset_byte);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
UInt64 offset = -static_cast<UInt64>(start);
|
||||||
|
size_t offset_byte = offset / word_size;
|
||||||
|
size_t offset_bit = (word_size - (offset % word_size)) % word_size;
|
||||||
|
if (offset_bit)
|
||||||
|
offset_byte++;
|
||||||
|
size_t size = src.getElementSize();
|
||||||
|
bool left_truncate = offset_byte > size;
|
||||||
|
shift_bit = left_truncate ? 0 : offset_bit;
|
||||||
|
slice = src.getSliceFromRight(offset_byte);
|
||||||
|
}
|
||||||
|
if (slice.size)
|
||||||
|
writeSliceWithLeftShift(slice, sink, shift_bit);
|
||||||
|
}
|
||||||
|
|
||||||
|
sink.next();
|
||||||
|
src.next();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class Source>
|
||||||
|
void bitSliceFromLeftConstantOffsetBounded(Source && src, StringSink && sink, size_t offset, ssize_t length) const
|
||||||
|
{
|
||||||
|
size_t offset_byte = offset / word_size;
|
||||||
|
size_t offset_bit = offset % word_size;
|
||||||
|
size_t shift_bit = offset_bit;
|
||||||
|
size_t length_byte = 0;
|
||||||
|
size_t over_bit = 0;
|
||||||
|
if (length > 0)
|
||||||
|
{
|
||||||
|
length_byte = (length + offset_bit) / word_size;
|
||||||
|
over_bit = (length + offset_bit) % word_size;
|
||||||
|
if (over_bit && (length_byte || over_bit > offset_bit))
|
||||||
|
length_byte++;
|
||||||
|
}
|
||||||
|
|
||||||
|
while (!src.isEnd())
|
||||||
|
{
|
||||||
|
ssize_t remain_byte = src.getElementSize() - offset_byte;
|
||||||
|
if (length < 0)
|
||||||
|
{
|
||||||
|
length_byte = std::max(remain_byte + (length / word_size), static_cast<ssize_t>(0));
|
||||||
|
over_bit = word_size + (length % word_size);
|
||||||
|
if (length_byte == 1 && over_bit <= offset_bit) {
|
||||||
|
length_byte = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
bool right_truncate = static_cast<ssize_t>(length_byte) > remain_byte;
|
||||||
|
size_t abandon_last_bit = (over_bit && !right_truncate) ? word_size - over_bit : 0;
|
||||||
|
auto slice = src.getSliceFromLeft(offset_byte, length_byte);
|
||||||
|
if (slice.size)
|
||||||
|
writeSliceWithLeftShift(slice, sink, shift_bit, abandon_last_bit);
|
||||||
|
|
||||||
|
sink.next();
|
||||||
|
src.next();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template <class Source>
|
||||||
|
void bitSliceFromRightConstantOffsetBounded(Source && src, StringSink && sink, size_t offset, ssize_t length) const
|
||||||
|
{
|
||||||
|
size_t offset_byte = offset / word_size;
|
||||||
|
size_t offset_bit = (word_size - (offset % word_size)) % word_size;
|
||||||
|
if (offset_bit)
|
||||||
|
offset_byte++;
|
||||||
|
size_t length_byte = 0;
|
||||||
|
size_t over_bit = 0;
|
||||||
|
if (length > 0)
|
||||||
|
{
|
||||||
|
length_byte = (length + offset_bit) / word_size;
|
||||||
|
over_bit = (length + offset_bit) % word_size;
|
||||||
|
if (over_bit && (length_byte || over_bit > offset_bit))
|
||||||
|
length_byte++;
|
||||||
|
}
|
||||||
|
|
||||||
|
while (!src.isEnd())
|
||||||
|
{
|
||||||
|
size_t size = src.getElementSize();
|
||||||
|
if (length < 0)
|
||||||
|
{
|
||||||
|
length_byte = std::max(static_cast<ssize_t>(offset_byte) + (length / word_size), static_cast<ssize_t>(0));
|
||||||
|
over_bit = word_size + (length % word_size);
|
||||||
|
if (length_byte == 1 && over_bit <= offset_bit) {
|
||||||
|
length_byte = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
bool left_truncate = offset_byte > size;
|
||||||
|
bool right_truncate = length_byte > offset_byte;
|
||||||
|
size_t shift_bit = left_truncate ? 0 : offset_bit;
|
||||||
|
size_t abandon_last_bit = (over_bit && !right_truncate) ? word_size - over_bit : 0;
|
||||||
|
auto slice = src.getSliceFromRight(offset_byte, length_byte);
|
||||||
|
if (slice.size)
|
||||||
|
writeSliceWithLeftShift(slice, sink, shift_bit, abandon_last_bit);
|
||||||
|
|
||||||
|
sink.next();
|
||||||
|
src.next();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class Source>
|
||||||
|
void bitSliceDynamicOffsetBounded(Source && src, StringSink && sink, const IColumn & offset_column, const IColumn & length_column) const
|
||||||
|
{
|
||||||
|
const bool is_offset_null = offset_column.onlyNull();
|
||||||
|
const auto * offset_nullable = typeid_cast<const ColumnNullable *>(&offset_column);
|
||||||
|
const ColumnUInt8::Container * offset_null_map = offset_nullable ? &offset_nullable->getNullMapData() : nullptr;
|
||||||
|
const IColumn * offset_nested_column = offset_nullable ? &offset_nullable->getNestedColumn() : &offset_column;
|
||||||
|
|
||||||
|
const bool is_length_null = length_column.onlyNull();
|
||||||
|
const auto * length_nullable = typeid_cast<const ColumnNullable *>(&length_column);
|
||||||
|
const ColumnUInt8::Container * length_null_map = length_nullable ? &length_nullable->getNullMapData() : nullptr;
|
||||||
|
const IColumn * length_nested_column = length_nullable ? &length_nullable->getNestedColumn() : &length_column;
|
||||||
|
|
||||||
|
|
||||||
|
while (!src.isEnd())
|
||||||
|
{
|
||||||
|
size_t row_num = src.rowNum();
|
||||||
|
bool has_offset = !is_offset_null && !(offset_null_map && (*offset_null_map)[row_num]);
|
||||||
|
bool has_length = !is_length_null && !(length_null_map && (*length_null_map)[row_num]);
|
||||||
|
Int64 start = has_offset ? offset_nested_column->getInt(row_num) : 1;
|
||||||
|
Int64 length = has_length ? length_nested_column->getInt(row_num) : static_cast<Int64>(src.getElementSize());
|
||||||
|
|
||||||
|
if (start && length)
|
||||||
|
{
|
||||||
|
bool left_offset = start > 0;
|
||||||
|
size_t offset = left_offset ? start - 1 : -start;
|
||||||
|
size_t offset_byte;
|
||||||
|
size_t offset_bit;
|
||||||
|
size_t shift_bit;
|
||||||
|
size_t length_byte;
|
||||||
|
size_t over_bit;
|
||||||
|
size_t size = src.getElementSize();
|
||||||
|
|
||||||
|
if (left_offset)
|
||||||
|
{
|
||||||
|
offset_byte = offset / word_size;
|
||||||
|
offset_bit = offset % word_size;
|
||||||
|
shift_bit = offset_bit;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
offset_byte = offset / word_size;
|
||||||
|
offset_bit = (word_size - (offset % word_size)) % word_size;
|
||||||
|
if (offset_bit)
|
||||||
|
offset_byte++;
|
||||||
|
bool left_truncate = offset_byte > size;
|
||||||
|
shift_bit = left_truncate ? 0 : offset_bit;
|
||||||
|
}
|
||||||
|
|
||||||
|
ssize_t remain_byte = left_offset ? size - offset_byte : offset_byte;
|
||||||
|
if (length > 0)
|
||||||
|
{
|
||||||
|
length_byte = (length + offset_bit) / word_size;
|
||||||
|
over_bit = (length + offset_bit) % word_size;
|
||||||
|
if (over_bit && (length_byte || (over_bit > offset_bit)))
|
||||||
|
length_byte++;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
length_byte = std::max(remain_byte + (static_cast<ssize_t>(length) / word_size), static_cast<ssize_t>(0));
|
||||||
|
over_bit = word_size + (length % word_size);
|
||||||
|
if (length_byte == 1 && over_bit <= offset_bit) {
|
||||||
|
length_byte = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool right_truncate = static_cast<ssize_t>(length_byte) > remain_byte;
|
||||||
|
size_t abandon_last_bit = (over_bit && !right_truncate) ? word_size - over_bit : 0;
|
||||||
|
auto slice = left_offset ? src.getSliceFromLeft(offset_byte, length_byte) : src.getSliceFromRight(offset_byte, length_byte);
|
||||||
|
if (slice.size)
|
||||||
|
writeSliceWithLeftShift(slice, sink, shift_bit, abandon_last_bit);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
sink.next();
|
||||||
|
src.next();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
void registerFunctionBitSlice(FunctionFactory & factory)
|
||||||
|
{
|
||||||
|
factory.registerFunction<FunctionBitSlice>();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
@ -20,6 +20,7 @@ void registerFunctionBitXor(FunctionFactory & factory);
|
|||||||
void registerFunctionBitNot(FunctionFactory & factory);
|
void registerFunctionBitNot(FunctionFactory & factory);
|
||||||
void registerFunctionBitShiftLeft(FunctionFactory & factory);
|
void registerFunctionBitShiftLeft(FunctionFactory & factory);
|
||||||
void registerFunctionBitShiftRight(FunctionFactory & factory);
|
void registerFunctionBitShiftRight(FunctionFactory & factory);
|
||||||
|
void registerFunctionBitSlice(FunctionFactory & factory);
|
||||||
void registerFunctionBitRotateLeft(FunctionFactory & factory);
|
void registerFunctionBitRotateLeft(FunctionFactory & factory);
|
||||||
void registerFunctionBitRotateRight(FunctionFactory & factory);
|
void registerFunctionBitRotateRight(FunctionFactory & factory);
|
||||||
void registerFunctionBitCount(FunctionFactory & factory);
|
void registerFunctionBitCount(FunctionFactory & factory);
|
||||||
@ -64,6 +65,7 @@ void registerFunctionsArithmetic(FunctionFactory & factory)
|
|||||||
registerFunctionBitRotateLeft(factory);
|
registerFunctionBitRotateLeft(factory);
|
||||||
registerFunctionBitRotateRight(factory);
|
registerFunctionBitRotateRight(factory);
|
||||||
registerFunctionBitCount(factory);
|
registerFunctionBitCount(factory);
|
||||||
|
registerFunctionBitSlice(factory);
|
||||||
registerFunctionLeast(factory);
|
registerFunctionLeast(factory);
|
||||||
registerFunctionGreatest(factory);
|
registerFunctionGreatest(factory);
|
||||||
registerFunctionBitTest(factory);
|
registerFunctionBitTest(factory);
|
||||||
|
@ -0,0 +1,163 @@
|
|||||||
|
Const Offset
|
||||||
|
1 01001000011001010110110001101100011011110000000000000000000000000000000000000000 01001000011001010110110001101100011011110000000000000000000000000000000000000000
|
||||||
|
2 1001000011001010110110001101100011011110000000000000000000000000000000000000000 10010000110010101101100011011000110111100000000000000000000000000000000000000000
|
||||||
|
3 001000011001010110110001101100011011110000000000000000000000000000000000000000 00100001100101011011000110110001101111000000000000000000000000000000000000000000
|
||||||
|
4 01000011001010110110001101100011011110000000000000000000000000000000000000000 01000011001010110110001101100011011110000000000000000000000000000000000000000000
|
||||||
|
5 1000011001010110110001101100011011110000000000000000000000000000000000000000 10000110010101101100011011000110111100000000000000000000000000000000000000000000
|
||||||
|
6 000011001010110110001101100011011110000000000000000000000000000000000000000 00001100101011011000110110001101111000000000000000000000000000000000000000000000
|
||||||
|
7 00011001010110110001101100011011110000000000000000000000000000000000000000 00011001010110110001101100011011110000000000000000000000000000000000000000000000
|
||||||
|
8 0011001010110110001101100011011110000000000000000000000000000000000000000 00110010101101100011011000110111100000000000000000000000000000000000000000000000
|
||||||
|
9 011001010110110001101100011011110000000000000000000000000000000000000000 011001010110110001101100011011110000000000000000000000000000000000000000
|
||||||
|
10 11001010110110001101100011011110000000000000000000000000000000000000000 110010101101100011011000110111100000000000000000000000000000000000000000
|
||||||
|
11 1001010110110001101100011011110000000000000000000000000000000000000000 100101011011000110110001101111000000000000000000000000000000000000000000
|
||||||
|
12 001010110110001101100011011110000000000000000000000000000000000000000 001010110110001101100011011110000000000000000000000000000000000000000000
|
||||||
|
13 01010110110001101100011011110000000000000000000000000000000000000000 010101101100011011000110111100000000000000000000000000000000000000000000
|
||||||
|
14 1010110110001101100011011110000000000000000000000000000000000000000 101011011000110110001101111000000000000000000000000000000000000000000000
|
||||||
|
15 010110110001101100011011110000000000000000000000000000000000000000 010110110001101100011011110000000000000000000000000000000000000000000000
|
||||||
|
16 10110110001101100011011110000000000000000000000000000000000000000 101101100011011000110111100000000000000000000000000000000000000000000000
|
||||||
|
-1 0 00000000
|
||||||
|
-2 00 00000000
|
||||||
|
-3 000 00000000
|
||||||
|
-4 0000 00000000
|
||||||
|
-5 00000 00000000
|
||||||
|
-6 000000 00000000
|
||||||
|
-7 0000000 00000000
|
||||||
|
-8 00000000 00000000
|
||||||
|
-9 000000000 0000000000000000
|
||||||
|
-10 0000000000 0000000000000000
|
||||||
|
-11 00000000000 0000000000000000
|
||||||
|
-12 000000000000 0000000000000000
|
||||||
|
-13 0000000000000 0000000000000000
|
||||||
|
-14 00000000000000 0000000000000000
|
||||||
|
-15 000000000000000 0000000000000000
|
||||||
|
-16 0000000000000000 0000000000000000
|
||||||
|
Const Offset, Const Length
|
||||||
|
1 1 0 00000000
|
||||||
|
2 2 10 10000000
|
||||||
|
3 3 001 00100000
|
||||||
|
4 4 0100 01000000
|
||||||
|
5 5 10000 10000000
|
||||||
|
6 6 000011 00001100
|
||||||
|
7 7 0001100 00011000
|
||||||
|
8 8 00110010 00110010
|
||||||
|
9 9 011001010 0110010100000000
|
||||||
|
10 10 1100101011 1100101011000000
|
||||||
|
11 11 10010101101 1001010110100000
|
||||||
|
12 12 001010110110 0010101101100000
|
||||||
|
13 13 0101011011000 0101011011000000
|
||||||
|
14 14 10101101100011 1010110110001100
|
||||||
|
15 15 010110110001101 0101101100011010
|
||||||
|
16 16 1011011000110110 1011011000110110
|
||||||
|
1 -1 0100100001100101011011000110110001101111000000000000000000000000000000000000000 01001000011001010110110001101100011011110000000000000000000000000000000000000000
|
||||||
|
2 -2 10010000110010101101100011011000110111100000000000000000000000000000000000000 10010000110010101101100011011000110111100000000000000000000000000000000000000000
|
||||||
|
3 -3 001000011001010110110001101100011011110000000000000000000000000000000000000 00100001100101011011000110110001101111000000000000000000000000000000000000000000
|
||||||
|
4 -4 0100001100101011011000110110001101111000000000000000000000000000000000000 01000011001010110110001101100011011110000000000000000000000000000000000000000000
|
||||||
|
5 -5 10000110010101101100011011000110111100000000000000000000000000000000000 100001100101011011000110110001101111000000000000000000000000000000000000
|
||||||
|
6 -6 000011001010110110001101100011011110000000000000000000000000000000000 000011001010110110001101100011011110000000000000000000000000000000000000
|
||||||
|
7 -7 0001100101011011000110110001101111000000000000000000000000000000000 000110010101101100011011000110111100000000000000000000000000000000000000
|
||||||
|
8 -8 00110010101101100011011000110111100000000000000000000000000000000 001100101011011000110110001101111000000000000000000000000000000000000000
|
||||||
|
9 -9 011001010110110001101100011011110000000000000000000000000000000 0110010101101100011011000110111100000000000000000000000000000000
|
||||||
|
10 -10 1100101011011000110110001101111000000000000000000000000000000 1100101011011000110110001101111000000000000000000000000000000000
|
||||||
|
11 -11 10010101101100011011000110111100000000000000000000000000000 1001010110110001101100011011110000000000000000000000000000000000
|
||||||
|
12 -12 001010110110001101100011011110000000000000000000000000000 0010101101100011011000110111100000000000000000000000000000000000
|
||||||
|
13 -13 0101011011000110110001101111000000000000000000000000000 01010110110001101100011011110000000000000000000000000000
|
||||||
|
14 -14 10101101100011011000110111100000000000000000000000000 10101101100011011000110111100000000000000000000000000000
|
||||||
|
15 -15 010110110001101100011011110000000000000000000000000 01011011000110110001101111000000000000000000000000000000
|
||||||
|
16 -16 1011011000110110001101111000000000000000000000000 10110110001101100011011110000000000000000000000000000000
|
||||||
|
-1 1 0 00000000
|
||||||
|
-2 2 00 00000000
|
||||||
|
-3 3 000 00000000
|
||||||
|
-4 4 0000 00000000
|
||||||
|
-5 5 00000 00000000
|
||||||
|
-6 6 000000 00000000
|
||||||
|
-7 7 0000000 00000000
|
||||||
|
-8 8 00000000 00000000
|
||||||
|
-9 9 000000000 0000000000000000
|
||||||
|
-10 10 0000000000 0000000000000000
|
||||||
|
-11 11 00000000000 0000000000000000
|
||||||
|
-12 12 000000000000 0000000000000000
|
||||||
|
-13 13 0000000000000 0000000000000000
|
||||||
|
-14 14 00000000000000 0000000000000000
|
||||||
|
-15 15 000000000000000 0000000000000000
|
||||||
|
-16 16 0000000000000000 0000000000000000
|
||||||
|
-1 -16
|
||||||
|
-2 -15
|
||||||
|
-3 -14
|
||||||
|
-4 -13
|
||||||
|
-5 -12
|
||||||
|
-6 -11
|
||||||
|
-7 -10
|
||||||
|
-8 -9
|
||||||
|
-9 -8 0 00000000
|
||||||
|
-10 -7 000 00000000
|
||||||
|
-11 -6 00000 00000000
|
||||||
|
-12 -5 0000000 00000000
|
||||||
|
-13 -4 000000000 0000000000000000
|
||||||
|
-14 -3 00000000000 0000000000000000
|
||||||
|
-15 -2 0000000000000 0000000000000000
|
||||||
|
-16 -1 000000000000000 0000000000000000
|
||||||
|
Dynamic Offset, Dynamic Length
|
||||||
|
0 0
|
||||||
|
1 1 0 00000000
|
||||||
|
2 2 10 10000000
|
||||||
|
3 3 001 00100000
|
||||||
|
4 4 0100 01000000
|
||||||
|
5 5 10000 10000000
|
||||||
|
6 6 000011 00001100
|
||||||
|
7 7 0001100 00011000
|
||||||
|
8 8 00110010 00110010
|
||||||
|
9 9 011001010 0110010100000000
|
||||||
|
10 10 1100101011 1100101011000000
|
||||||
|
11 11 10010101101 1001010110100000
|
||||||
|
12 12 001010110110 0010101101100000
|
||||||
|
13 13 0101011011000 0101011011000000
|
||||||
|
14 14 10101101100011 1010110110001100
|
||||||
|
15 15 010110110001101 0101101100011010
|
||||||
|
0 0
|
||||||
|
1 -1 0100100001100101011011000110110001101111000000000000000000000000000000000000000 01001000011001010110110001101100011011110000000000000000000000000000000000000000
|
||||||
|
2 -2 10010000110010101101100011011000110111100000000000000000000000000000000000000 10010000110010101101100011011000110111100000000000000000000000000000000000000000
|
||||||
|
3 -3 001000011001010110110001101100011011110000000000000000000000000000000000000 00100001100101011011000110110001101111000000000000000000000000000000000000000000
|
||||||
|
4 -4 0100001100101011011000110110001101111000000000000000000000000000000000000 01000011001010110110001101100011011110000000000000000000000000000000000000000000
|
||||||
|
5 -5 10000110010101101100011011000110111100000000000000000000000000000000000 100001100101011011000110110001101111000000000000000000000000000000000000
|
||||||
|
6 -6 000011001010110110001101100011011110000000000000000000000000000000000 000011001010110110001101100011011110000000000000000000000000000000000000
|
||||||
|
7 -7 0001100101011011000110110001101111000000000000000000000000000000000 000110010101101100011011000110111100000000000000000000000000000000000000
|
||||||
|
8 -8 00110010101101100011011000110111100000000000000000000000000000000 001100101011011000110110001101111000000000000000000000000000000000000000
|
||||||
|
9 -9 011001010110110001101100011011110000000000000000000000000000000 0110010101101100011011000110111100000000000000000000000000000000
|
||||||
|
10 -10 1100101011011000110110001101111000000000000000000000000000000 1100101011011000110110001101111000000000000000000000000000000000
|
||||||
|
11 -11 10010101101100011011000110111100000000000000000000000000000 1001010110110001101100011011110000000000000000000000000000000000
|
||||||
|
12 -12 001010110110001101100011011110000000000000000000000000000 0010101101100011011000110111100000000000000000000000000000000000
|
||||||
|
13 -13 0101011011000110110001101111000000000000000000000000000 01010110110001101100011011110000000000000000000000000000
|
||||||
|
14 -14 10101101100011011000110111100000000000000000000000000 10101101100011011000110111100000000000000000000000000000
|
||||||
|
15 -15 010110110001101100011011110000000000000000000000000 01011011000110110001101111000000000000000000000000000000
|
||||||
|
0 -16
|
||||||
|
-1 -15
|
||||||
|
-2 -14
|
||||||
|
-3 -13
|
||||||
|
-4 -12
|
||||||
|
-5 -11
|
||||||
|
-6 -10
|
||||||
|
-7 -9
|
||||||
|
-8 -8
|
||||||
|
-9 -7 00 00000000
|
||||||
|
-10 -6 0000 00000000
|
||||||
|
-11 -5 000000 00000000
|
||||||
|
-12 -4 00000000 00000000
|
||||||
|
-13 -3 0000000000 0000000000000000
|
||||||
|
-14 -2 000000000000 0000000000000000
|
||||||
|
-15 -1 00000000000000 0000000000000000
|
||||||
|
0 0
|
||||||
|
-1 1 0 00000000
|
||||||
|
-2 2 00 00000000
|
||||||
|
-3 3 000 00000000
|
||||||
|
-4 4 0000 00000000
|
||||||
|
-5 5 00000 00000000
|
||||||
|
-6 6 000000 00000000
|
||||||
|
-7 7 0000000 00000000
|
||||||
|
-8 8 00000000 00000000
|
||||||
|
-9 9 000000000 0000000000000000
|
||||||
|
-10 10 0000000000 0000000000000000
|
||||||
|
-11 11 00000000000 0000000000000000
|
||||||
|
-12 12 000000000000 0000000000000000
|
||||||
|
-13 13 0000000000000 0000000000000000
|
||||||
|
-14 14 00000000000000 0000000000000000
|
||||||
|
-15 15 000000000000000 0000000000000000
|
111
tests/queries/0_stateless/02154_bit_slice_for_fixedstring.sql
Normal file
111
tests/queries/0_stateless/02154_bit_slice_for_fixedstring.sql
Normal file
@ -0,0 +1,111 @@
|
|||||||
|
SELECT 'Const Offset';
|
||||||
|
select 1, subString(bin(toFixedString('Hello', 10)), 1), bin(bitSlice(toFixedString('Hello', 10), 1));
|
||||||
|
select 2, subString(bin(toFixedString('Hello', 10)), 2), bin(bitSlice(toFixedString('Hello', 10), 2));
|
||||||
|
select 3, subString(bin(toFixedString('Hello', 10)), 3), bin(bitSlice(toFixedString('Hello', 10), 3));
|
||||||
|
select 4, subString(bin(toFixedString('Hello', 10)), 4), bin(bitSlice(toFixedString('Hello', 10), 4));
|
||||||
|
select 5, subString(bin(toFixedString('Hello', 10)), 5), bin(bitSlice(toFixedString('Hello', 10), 5));
|
||||||
|
select 6, subString(bin(toFixedString('Hello', 10)), 6), bin(bitSlice(toFixedString('Hello', 10), 6));
|
||||||
|
select 7, subString(bin(toFixedString('Hello', 10)), 7), bin(bitSlice(toFixedString('Hello', 10), 7));
|
||||||
|
select 8, subString(bin(toFixedString('Hello', 10)), 8), bin(bitSlice(toFixedString('Hello', 10), 8));
|
||||||
|
select 9, subString(bin(toFixedString('Hello', 10)), 9), bin(bitSlice(toFixedString('Hello', 10), 9));
|
||||||
|
select 10, subString(bin(toFixedString('Hello', 10)), 10), bin(bitSlice(toFixedString('Hello', 10), 10));
|
||||||
|
select 11, subString(bin(toFixedString('Hello', 10)), 11), bin(bitSlice(toFixedString('Hello', 10), 11));
|
||||||
|
select 12, subString(bin(toFixedString('Hello', 10)), 12), bin(bitSlice(toFixedString('Hello', 10), 12));
|
||||||
|
select 13, subString(bin(toFixedString('Hello', 10)), 13), bin(bitSlice(toFixedString('Hello', 10), 13));
|
||||||
|
select 14, subString(bin(toFixedString('Hello', 10)), 14), bin(bitSlice(toFixedString('Hello', 10), 14));
|
||||||
|
select 15, subString(bin(toFixedString('Hello', 10)), 15), bin(bitSlice(toFixedString('Hello', 10), 15));
|
||||||
|
select 16, subString(bin(toFixedString('Hello', 10)), 16), bin(bitSlice(toFixedString('Hello', 10), 16));
|
||||||
|
|
||||||
|
select -1, subString(bin(toFixedString('Hello', 10)), -1), bin(bitSlice(toFixedString('Hello', 10), -1));
|
||||||
|
select -2, subString(bin(toFixedString('Hello', 10)), -2), bin(bitSlice(toFixedString('Hello', 10), -2));
|
||||||
|
select -3, subString(bin(toFixedString('Hello', 10)), -3), bin(bitSlice(toFixedString('Hello', 10), -3));
|
||||||
|
select -4, subString(bin(toFixedString('Hello', 10)), -4), bin(bitSlice(toFixedString('Hello', 10), -4));
|
||||||
|
select -5, subString(bin(toFixedString('Hello', 10)), -5), bin(bitSlice(toFixedString('Hello', 10), -5));
|
||||||
|
select -6, subString(bin(toFixedString('Hello', 10)), -6), bin(bitSlice(toFixedString('Hello', 10), -6));
|
||||||
|
select -7, subString(bin(toFixedString('Hello', 10)), -7), bin(bitSlice(toFixedString('Hello', 10), -7));
|
||||||
|
select -8, subString(bin(toFixedString('Hello', 10)), -8), bin(bitSlice(toFixedString('Hello', 10), -8));
|
||||||
|
select -9, subString(bin(toFixedString('Hello', 10)), -9), bin(bitSlice(toFixedString('Hello', 10), -9));
|
||||||
|
select -10, subString(bin(toFixedString('Hello', 10)), -10), bin(bitSlice(toFixedString('Hello', 10), -10));
|
||||||
|
select -11, subString(bin(toFixedString('Hello', 10)), -11), bin(bitSlice(toFixedString('Hello', 10), -11));
|
||||||
|
select -12, subString(bin(toFixedString('Hello', 10)), -12), bin(bitSlice(toFixedString('Hello', 10), -12));
|
||||||
|
select -13, subString(bin(toFixedString('Hello', 10)), -13), bin(bitSlice(toFixedString('Hello', 10), -13));
|
||||||
|
select -14, subString(bin(toFixedString('Hello', 10)), -14), bin(bitSlice(toFixedString('Hello', 10), -14));
|
||||||
|
select -15, subString(bin(toFixedString('Hello', 10)), -15), bin(bitSlice(toFixedString('Hello', 10), -15));
|
||||||
|
select -16, subString(bin(toFixedString('Hello', 10)), -16), bin(bitSlice(toFixedString('Hello', 10), -16));
|
||||||
|
|
||||||
|
|
||||||
|
SELECT 'Const Offset, Const Length';
|
||||||
|
select 1, 1, subString(bin(toFixedString('Hello', 10)), 1, 1), bin(bitSlice(toFixedString('Hello', 10), 1, 1));
|
||||||
|
select 2, 2, subString(bin(toFixedString('Hello', 10)), 2, 2), bin(bitSlice(toFixedString('Hello', 10), 2, 2));
|
||||||
|
select 3, 3, subString(bin(toFixedString('Hello', 10)), 3, 3), bin(bitSlice(toFixedString('Hello', 10), 3, 3));
|
||||||
|
select 4, 4, subString(bin(toFixedString('Hello', 10)), 4, 4), bin(bitSlice(toFixedString('Hello', 10), 4, 4));
|
||||||
|
select 5, 5, subString(bin(toFixedString('Hello', 10)), 5, 5), bin(bitSlice(toFixedString('Hello', 10), 5, 5));
|
||||||
|
select 6, 6, subString(bin(toFixedString('Hello', 10)), 6, 6), bin(bitSlice(toFixedString('Hello', 10), 6, 6));
|
||||||
|
select 7, 7, subString(bin(toFixedString('Hello', 10)), 7, 7), bin(bitSlice(toFixedString('Hello', 10), 7, 7));
|
||||||
|
select 8, 8, subString(bin(toFixedString('Hello', 10)), 8, 8), bin(bitSlice(toFixedString('Hello', 10), 8, 8));
|
||||||
|
select 9, 9, subString(bin(toFixedString('Hello', 10)), 9, 9), bin(bitSlice(toFixedString('Hello', 10), 9, 9));
|
||||||
|
select 10, 10, subString(bin(toFixedString('Hello', 10)), 10, 10), bin(bitSlice(toFixedString('Hello', 10), 10, 10));
|
||||||
|
select 11, 11, subString(bin(toFixedString('Hello', 10)), 11, 11), bin(bitSlice(toFixedString('Hello', 10), 11, 11));
|
||||||
|
select 12, 12, subString(bin(toFixedString('Hello', 10)), 12, 12), bin(bitSlice(toFixedString('Hello', 10), 12, 12));
|
||||||
|
select 13, 13, subString(bin(toFixedString('Hello', 10)), 13, 13), bin(bitSlice(toFixedString('Hello', 10), 13, 13));
|
||||||
|
select 14, 14, subString(bin(toFixedString('Hello', 10)), 14, 14), bin(bitSlice(toFixedString('Hello', 10), 14, 14));
|
||||||
|
select 15, 15, subString(bin(toFixedString('Hello', 10)), 15, 15), bin(bitSlice(toFixedString('Hello', 10), 15, 15));
|
||||||
|
select 16, 16, subString(bin(toFixedString('Hello', 10)), 16, 16), bin(bitSlice(toFixedString('Hello', 10), 16, 16));
|
||||||
|
|
||||||
|
select 1, -1, subString(bin(toFixedString('Hello', 10)), 1, -1), bin(bitSlice(toFixedString('Hello', 10), 1, -1));
|
||||||
|
select 2, -2, subString(bin(toFixedString('Hello', 10)), 2, -2), bin(bitSlice(toFixedString('Hello', 10), 2, -2));
|
||||||
|
select 3, -3, subString(bin(toFixedString('Hello', 10)), 3, -3), bin(bitSlice(toFixedString('Hello', 10), 3, -3));
|
||||||
|
select 4, -4, subString(bin(toFixedString('Hello', 10)), 4, -4), bin(bitSlice(toFixedString('Hello', 10), 4, -4));
|
||||||
|
select 5, -5, subString(bin(toFixedString('Hello', 10)), 5, -5), bin(bitSlice(toFixedString('Hello', 10), 5, -5));
|
||||||
|
select 6, -6, subString(bin(toFixedString('Hello', 10)), 6, -6), bin(bitSlice(toFixedString('Hello', 10), 6, -6));
|
||||||
|
select 7, -7, subString(bin(toFixedString('Hello', 10)), 7, -7), bin(bitSlice(toFixedString('Hello', 10), 7, -7));
|
||||||
|
select 8, -8, subString(bin(toFixedString('Hello', 10)), 8, -8), bin(bitSlice(toFixedString('Hello', 10), 8, -8));
|
||||||
|
select 9, -9, subString(bin(toFixedString('Hello', 10)), 9, -9), bin(bitSlice(toFixedString('Hello', 10), 9, -9));
|
||||||
|
select 10, -10, subString(bin(toFixedString('Hello', 10)), 10, -10), bin(bitSlice(toFixedString('Hello', 10), 10, -10));
|
||||||
|
select 11, -11, subString(bin(toFixedString('Hello', 10)), 11, -11), bin(bitSlice(toFixedString('Hello', 10), 11, -11));
|
||||||
|
select 12, -12, subString(bin(toFixedString('Hello', 10)), 12, -12), bin(bitSlice(toFixedString('Hello', 10), 12, -12));
|
||||||
|
select 13, -13, subString(bin(toFixedString('Hello', 10)), 13, -13), bin(bitSlice(toFixedString('Hello', 10), 13, -13));
|
||||||
|
select 14, -14, subString(bin(toFixedString('Hello', 10)), 14, -14), bin(bitSlice(toFixedString('Hello', 10), 14, -14));
|
||||||
|
select 15, -15, subString(bin(toFixedString('Hello', 10)), 15, -15), bin(bitSlice(toFixedString('Hello', 10), 15, -15));
|
||||||
|
select 16, -16, subString(bin(toFixedString('Hello', 10)), 16, -16), bin(bitSlice(toFixedString('Hello', 10), 16, -16));
|
||||||
|
|
||||||
|
select -1, 1, subString(bin(toFixedString('Hello', 10)), -1, 1), bin(bitSlice(toFixedString('Hello', 10), -1, 1));
|
||||||
|
select -2, 2, subString(bin(toFixedString('Hello', 10)), -2, 2), bin(bitSlice(toFixedString('Hello', 10), -2, 2));
|
||||||
|
select -3, 3, subString(bin(toFixedString('Hello', 10)), -3, 3), bin(bitSlice(toFixedString('Hello', 10), -3, 3));
|
||||||
|
select -4, 4, subString(bin(toFixedString('Hello', 10)), -4, 4), bin(bitSlice(toFixedString('Hello', 10), -4, 4));
|
||||||
|
select -5, 5, subString(bin(toFixedString('Hello', 10)), -5, 5), bin(bitSlice(toFixedString('Hello', 10), -5, 5));
|
||||||
|
select -6, 6, subString(bin(toFixedString('Hello', 10)), -6, 6), bin(bitSlice(toFixedString('Hello', 10), -6, 6));
|
||||||
|
select -7, 7, subString(bin(toFixedString('Hello', 10)), -7, 7), bin(bitSlice(toFixedString('Hello', 10), -7, 7));
|
||||||
|
select -8, 8, subString(bin(toFixedString('Hello', 10)), -8, 8), bin(bitSlice(toFixedString('Hello', 10), -8, 8));
|
||||||
|
select -9, 9, subString(bin(toFixedString('Hello', 10)), -9, 9), bin(bitSlice(toFixedString('Hello', 10), -9, 9));
|
||||||
|
select -10, 10, subString(bin(toFixedString('Hello', 10)), -10, 10), bin(bitSlice(toFixedString('Hello', 10), -10, 10));
|
||||||
|
select -11, 11, subString(bin(toFixedString('Hello', 10)), -11, 11), bin(bitSlice(toFixedString('Hello', 10), -11, 11));
|
||||||
|
select -12, 12, subString(bin(toFixedString('Hello', 10)), -12, 12), bin(bitSlice(toFixedString('Hello', 10), -12, 12));
|
||||||
|
select -13, 13, subString(bin(toFixedString('Hello', 10)), -13, 13), bin(bitSlice(toFixedString('Hello', 10), -13, 13));
|
||||||
|
select -14, 14, subString(bin(toFixedString('Hello', 10)), -14, 14), bin(bitSlice(toFixedString('Hello', 10), -14, 14));
|
||||||
|
select -15, 15, subString(bin(toFixedString('Hello', 10)), -15, 15), bin(bitSlice(toFixedString('Hello', 10), -15, 15));
|
||||||
|
select -16, 16, subString(bin(toFixedString('Hello', 10)), -16, 16), bin(bitSlice(toFixedString('Hello', 10), -16, 16));
|
||||||
|
|
||||||
|
select -1, -16, subString(bin(toFixedString('Hello', 10)), -1, -16), bin(bitSlice(toFixedString('Hello', 10), -1, -16));
|
||||||
|
select -2, -15, subString(bin(toFixedString('Hello', 10)), -2, -15), bin(bitSlice(toFixedString('Hello', 10), -2, -15));
|
||||||
|
select -3, -14, subString(bin(toFixedString('Hello', 10)), -3, -14), bin(bitSlice(toFixedString('Hello', 10), -3, -14));
|
||||||
|
select -4, -13, subString(bin(toFixedString('Hello', 10)), -4, -13), bin(bitSlice(toFixedString('Hello', 10), -4, -13));
|
||||||
|
select -5, -12, subString(bin(toFixedString('Hello', 10)), -5, -12), bin(bitSlice(toFixedString('Hello', 10), -5, -12));
|
||||||
|
select -6, -11, subString(bin(toFixedString('Hello', 10)), -6, -11), bin(bitSlice(toFixedString('Hello', 10), -6, -11));
|
||||||
|
select -7, -10, subString(bin(toFixedString('Hello', 10)), -7, -10), bin(bitSlice(toFixedString('Hello', 10), -7, -10));
|
||||||
|
select -8, -9, subString(bin(toFixedString('Hello', 10)), -8, -9), bin(bitSlice(toFixedString('Hello', 10), -8, -9));
|
||||||
|
select -9, -8, subString(bin(toFixedString('Hello', 10)), -9, -8), bin(bitSlice(toFixedString('Hello', 10), -9, -8));
|
||||||
|
select -10, -7, subString(bin(toFixedString('Hello', 10)), -10, -7), bin(bitSlice(toFixedString('Hello', 10), -10, -7));
|
||||||
|
select -11, -6, subString(bin(toFixedString('Hello', 10)), -11, -6), bin(bitSlice(toFixedString('Hello', 10), -11, -6));
|
||||||
|
select -12, -5, subString(bin(toFixedString('Hello', 10)), -12, -5), bin(bitSlice(toFixedString('Hello', 10), -12, -5));
|
||||||
|
select -13, -4, subString(bin(toFixedString('Hello', 10)), -13, -4), bin(bitSlice(toFixedString('Hello', 10), -13, -4));
|
||||||
|
select -14, -3, subString(bin(toFixedString('Hello', 10)), -14, -3), bin(bitSlice(toFixedString('Hello', 10), -14, -3));
|
||||||
|
select -15, -2, subString(bin(toFixedString('Hello', 10)), -15, -2), bin(bitSlice(toFixedString('Hello', 10), -15, -2));
|
||||||
|
select -16, -1, subString(bin(toFixedString('Hello', 10)), -16, -1), bin(bitSlice(toFixedString('Hello', 10), -16, -1));
|
||||||
|
|
||||||
|
select 'Dynamic Offset, Dynamic Length';
|
||||||
|
|
||||||
|
select number, number, subString(bin(toFixedString('Hello', 10)), number, number), bin(bitSlice(toFixedString('Hello', 10), number, number)) from numbers(16);
|
||||||
|
select number, -number, subString(bin(toFixedString('Hello', 10)), number, -number), bin(bitSlice(toFixedString('Hello', 10), number, -number)) from numbers(16);
|
||||||
|
select -number, -16+number, subString(bin(toFixedString('Hello', 10)), -number, -16+number), bin(bitSlice(toFixedString('Hello', 10), -number, -16+number)) from numbers(16);
|
||||||
|
select -number, number, subString(bin(toFixedString('Hello', 10)), -number, number), bin(bitSlice(toFixedString('Hello', 10), -number, number)) from numbers(16);
|
163
tests/queries/0_stateless/02154_bit_slice_for_string.reference
Normal file
163
tests/queries/0_stateless/02154_bit_slice_for_string.reference
Normal file
@ -0,0 +1,163 @@
|
|||||||
|
Const Offset
|
||||||
|
1 0100100001100101011011000110110001101111 0100100001100101011011000110110001101111
|
||||||
|
2 100100001100101011011000110110001101111 1001000011001010110110001101100011011110
|
||||||
|
3 00100001100101011011000110110001101111 0010000110010101101100011011000110111100
|
||||||
|
4 0100001100101011011000110110001101111 0100001100101011011000110110001101111000
|
||||||
|
5 100001100101011011000110110001101111 1000011001010110110001101100011011110000
|
||||||
|
6 00001100101011011000110110001101111 0000110010101101100011011000110111100000
|
||||||
|
7 0001100101011011000110110001101111 0001100101011011000110110001101111000000
|
||||||
|
8 001100101011011000110110001101111 0011001010110110001101100011011110000000
|
||||||
|
9 01100101011011000110110001101111 01100101011011000110110001101111
|
||||||
|
10 1100101011011000110110001101111 11001010110110001101100011011110
|
||||||
|
11 100101011011000110110001101111 10010101101100011011000110111100
|
||||||
|
12 00101011011000110110001101111 00101011011000110110001101111000
|
||||||
|
13 0101011011000110110001101111 01010110110001101100011011110000
|
||||||
|
14 101011011000110110001101111 10101101100011011000110111100000
|
||||||
|
15 01011011000110110001101111 01011011000110110001101111000000
|
||||||
|
16 1011011000110110001101111 10110110001101100011011110000000
|
||||||
|
-1 1 10000000
|
||||||
|
-2 11 11000000
|
||||||
|
-3 111 11100000
|
||||||
|
-4 1111 11110000
|
||||||
|
-5 01111 01111000
|
||||||
|
-6 101111 10111100
|
||||||
|
-7 1101111 11011110
|
||||||
|
-8 01101111 01101111
|
||||||
|
-9 001101111 0011011110000000
|
||||||
|
-10 0001101111 0001101111000000
|
||||||
|
-11 10001101111 1000110111100000
|
||||||
|
-12 110001101111 1100011011110000
|
||||||
|
-13 0110001101111 0110001101111000
|
||||||
|
-14 10110001101111 1011000110111100
|
||||||
|
-15 110110001101111 1101100011011110
|
||||||
|
-16 0110110001101111 0110110001101111
|
||||||
|
Const Offset, Const Length
|
||||||
|
1 1 0 00000000
|
||||||
|
2 2 10 10000000
|
||||||
|
3 3 001 00100000
|
||||||
|
4 4 0100 01000000
|
||||||
|
5 5 10000 10000000
|
||||||
|
6 6 000011 00001100
|
||||||
|
7 7 0001100 00011000
|
||||||
|
8 8 00110010 00110010
|
||||||
|
9 9 011001010 0110010100000000
|
||||||
|
10 10 1100101011 1100101011000000
|
||||||
|
11 11 10010101101 1001010110100000
|
||||||
|
12 12 001010110110 0010101101100000
|
||||||
|
13 13 0101011011000 0101011011000000
|
||||||
|
14 14 10101101100011 1010110110001100
|
||||||
|
15 15 010110110001101 0101101100011010
|
||||||
|
16 16 1011011000110110 1011011000110110
|
||||||
|
1 -1 010010000110010101101100011011000110111 0100100001100101011011000110110001101110
|
||||||
|
2 -2 1001000011001010110110001101100011011 1001000011001010110110001101100011011000
|
||||||
|
3 -3 00100001100101011011000110110001101 0010000110010101101100011011000110100000
|
||||||
|
4 -4 010000110010101101100011011000110 0100001100101011011000110110001100000000
|
||||||
|
5 -5 1000011001010110110001101100011 10000110010101101100011011000110
|
||||||
|
6 -6 00001100101011011000110110001 00001100101011011000110110001000
|
||||||
|
7 -7 000110010101101100011011000 00011001010110110001101100000000
|
||||||
|
8 -8 0011001010110110001101100 00110010101101100011011000000000
|
||||||
|
9 -9 01100101011011000110110 011001010110110001101100
|
||||||
|
10 -10 110010101101100011011 110010101101100011011000
|
||||||
|
11 -11 1001010110110001101 100101011011000110100000
|
||||||
|
12 -12 00101011011000110 001010110110001100000000
|
||||||
|
13 -13 010101101100011 0101011011000110
|
||||||
|
14 -14 1010110110001 1010110110001000
|
||||||
|
15 -15 01011011000 0101101100000000
|
||||||
|
16 -16 101101100 1011011000000000
|
||||||
|
-1 1 1 10000000
|
||||||
|
-2 2 11 11000000
|
||||||
|
-3 3 111 11100000
|
||||||
|
-4 4 1111 11110000
|
||||||
|
-5 5 01111 01111000
|
||||||
|
-6 6 101111 10111100
|
||||||
|
-7 7 1101111 11011110
|
||||||
|
-8 8 01101111 01101111
|
||||||
|
-9 9 001101111 0011011110000000
|
||||||
|
-10 10 0001101111 0001101111000000
|
||||||
|
-11 11 10001101111 1000110111100000
|
||||||
|
-12 12 110001101111 1100011011110000
|
||||||
|
-13 13 0110001101111 0110001101111000
|
||||||
|
-14 14 10110001101111 1011000110111100
|
||||||
|
-15 15 110110001101111 1101100011011110
|
||||||
|
-16 16 0110110001101111 0110110001101111
|
||||||
|
-1 -16
|
||||||
|
-2 -15
|
||||||
|
-3 -14
|
||||||
|
-4 -13
|
||||||
|
-5 -12
|
||||||
|
-6 -11
|
||||||
|
-7 -10
|
||||||
|
-8 -9
|
||||||
|
-9 -8 0 00000000
|
||||||
|
-10 -7 000 00000000
|
||||||
|
-11 -6 10001 10001000
|
||||||
|
-12 -5 1100011 11000110
|
||||||
|
-13 -4 011000110 0110001100000000
|
||||||
|
-14 -3 10110001101 1011000110100000
|
||||||
|
-15 -2 1101100011011 1101100011011000
|
||||||
|
-16 -1 011011000110111 0110110001101110
|
||||||
|
Dynamic Offset, Dynamic Length
|
||||||
|
0 0
|
||||||
|
1 1 0 00000000
|
||||||
|
2 2 10 10000000
|
||||||
|
3 3 001 00100000
|
||||||
|
4 4 0100 01000000
|
||||||
|
5 5 10000 10000000
|
||||||
|
6 6 000011 00001100
|
||||||
|
7 7 0001100 00011000
|
||||||
|
8 8 00110010 00110010
|
||||||
|
9 9 011001010 0110010100000000
|
||||||
|
10 10 1100101011 1100101011000000
|
||||||
|
11 11 10010101101 1001010110100000
|
||||||
|
12 12 001010110110 0010101101100000
|
||||||
|
13 13 0101011011000 0101011011000000
|
||||||
|
14 14 10101101100011 1010110110001100
|
||||||
|
15 15 010110110001101 0101101100011010
|
||||||
|
0 0
|
||||||
|
1 -1 010010000110010101101100011011000110111 0100100001100101011011000110110001101110
|
||||||
|
2 -2 1001000011001010110110001101100011011 1001000011001010110110001101100011011000
|
||||||
|
3 -3 00100001100101011011000110110001101 0010000110010101101100011011000110100000
|
||||||
|
4 -4 010000110010101101100011011000110 0100001100101011011000110110001100000000
|
||||||
|
5 -5 1000011001010110110001101100011 10000110010101101100011011000110
|
||||||
|
6 -6 00001100101011011000110110001 00001100101011011000110110001000
|
||||||
|
7 -7 000110010101101100011011000 00011001010110110001101100000000
|
||||||
|
8 -8 0011001010110110001101100 00110010101101100011011000000000
|
||||||
|
9 -9 01100101011011000110110 011001010110110001101100
|
||||||
|
10 -10 110010101101100011011 110010101101100011011000
|
||||||
|
11 -11 1001010110110001101 100101011011000110100000
|
||||||
|
12 -12 00101011011000110 001010110110001100000000
|
||||||
|
13 -13 010101101100011 0101011011000110
|
||||||
|
14 -14 1010110110001 1010110110001000
|
||||||
|
15 -15 01011011000 0101101100000000
|
||||||
|
0 -16
|
||||||
|
-1 -15
|
||||||
|
-2 -14
|
||||||
|
-3 -13
|
||||||
|
-4 -12
|
||||||
|
-5 -11
|
||||||
|
-6 -10
|
||||||
|
-7 -9
|
||||||
|
-8 -8
|
||||||
|
-9 -7 00 00000000
|
||||||
|
-10 -6 0001 00010000
|
||||||
|
-11 -5 100011 10001100
|
||||||
|
-12 -4 11000110 11000110
|
||||||
|
-13 -3 0110001101 0110001101000000
|
||||||
|
-14 -2 101100011011 1011000110110000
|
||||||
|
-15 -1 11011000110111 1101100011011100
|
||||||
|
0 0
|
||||||
|
-1 1 1 10000000
|
||||||
|
-2 2 11 11000000
|
||||||
|
-3 3 111 11100000
|
||||||
|
-4 4 1111 11110000
|
||||||
|
-5 5 01111 01111000
|
||||||
|
-6 6 101111 10111100
|
||||||
|
-7 7 1101111 11011110
|
||||||
|
-8 8 01101111 01101111
|
||||||
|
-9 9 001101111 0011011110000000
|
||||||
|
-10 10 0001101111 0001101111000000
|
||||||
|
-11 11 10001101111 1000110111100000
|
||||||
|
-12 12 110001101111 1100011011110000
|
||||||
|
-13 13 0110001101111 0110001101111000
|
||||||
|
-14 14 10110001101111 1011000110111100
|
||||||
|
-15 15 110110001101111 1101100011011110
|
111
tests/queries/0_stateless/02154_bit_slice_for_string.sql
Normal file
111
tests/queries/0_stateless/02154_bit_slice_for_string.sql
Normal file
@ -0,0 +1,111 @@
|
|||||||
|
SELECT 'Const Offset';
|
||||||
|
select 1, subString(bin('Hello'), 1), bin(bitSlice('Hello', 1));
|
||||||
|
select 2, subString(bin('Hello'), 2), bin(bitSlice('Hello', 2));
|
||||||
|
select 3, subString(bin('Hello'), 3), bin(bitSlice('Hello', 3));
|
||||||
|
select 4, subString(bin('Hello'), 4), bin(bitSlice('Hello', 4));
|
||||||
|
select 5, subString(bin('Hello'), 5), bin(bitSlice('Hello', 5));
|
||||||
|
select 6, subString(bin('Hello'), 6), bin(bitSlice('Hello', 6));
|
||||||
|
select 7, subString(bin('Hello'), 7), bin(bitSlice('Hello', 7));
|
||||||
|
select 8, subString(bin('Hello'), 8), bin(bitSlice('Hello', 8));
|
||||||
|
select 9, subString(bin('Hello'), 9), bin(bitSlice('Hello', 9));
|
||||||
|
select 10, subString(bin('Hello'), 10), bin(bitSlice('Hello', 10));
|
||||||
|
select 11, subString(bin('Hello'), 11), bin(bitSlice('Hello', 11));
|
||||||
|
select 12, subString(bin('Hello'), 12), bin(bitSlice('Hello', 12));
|
||||||
|
select 13, subString(bin('Hello'), 13), bin(bitSlice('Hello', 13));
|
||||||
|
select 14, subString(bin('Hello'), 14), bin(bitSlice('Hello', 14));
|
||||||
|
select 15, subString(bin('Hello'), 15), bin(bitSlice('Hello', 15));
|
||||||
|
select 16, subString(bin('Hello'), 16), bin(bitSlice('Hello', 16));
|
||||||
|
|
||||||
|
select -1, subString(bin('Hello'), -1), bin(bitSlice('Hello', -1));
|
||||||
|
select -2, subString(bin('Hello'), -2), bin(bitSlice('Hello', -2));
|
||||||
|
select -3, subString(bin('Hello'), -3), bin(bitSlice('Hello', -3));
|
||||||
|
select -4, subString(bin('Hello'), -4), bin(bitSlice('Hello', -4));
|
||||||
|
select -5, subString(bin('Hello'), -5), bin(bitSlice('Hello', -5));
|
||||||
|
select -6, subString(bin('Hello'), -6), bin(bitSlice('Hello', -6));
|
||||||
|
select -7, subString(bin('Hello'), -7), bin(bitSlice('Hello', -7));
|
||||||
|
select -8, subString(bin('Hello'), -8), bin(bitSlice('Hello', -8));
|
||||||
|
select -9, subString(bin('Hello'), -9), bin(bitSlice('Hello', -9));
|
||||||
|
select -10, subString(bin('Hello'), -10), bin(bitSlice('Hello', -10));
|
||||||
|
select -11, subString(bin('Hello'), -11), bin(bitSlice('Hello', -11));
|
||||||
|
select -12, subString(bin('Hello'), -12), bin(bitSlice('Hello', -12));
|
||||||
|
select -13, subString(bin('Hello'), -13), bin(bitSlice('Hello', -13));
|
||||||
|
select -14, subString(bin('Hello'), -14), bin(bitSlice('Hello', -14));
|
||||||
|
select -15, subString(bin('Hello'), -15), bin(bitSlice('Hello', -15));
|
||||||
|
select -16, subString(bin('Hello'), -16), bin(bitSlice('Hello', -16));
|
||||||
|
|
||||||
|
|
||||||
|
SELECT 'Const Offset, Const Length';
|
||||||
|
select 1, 1, subString(bin('Hello'), 1, 1), bin(bitSlice('Hello', 1, 1));
|
||||||
|
select 2, 2, subString(bin('Hello'), 2, 2), bin(bitSlice('Hello', 2, 2));
|
||||||
|
select 3, 3, subString(bin('Hello'), 3, 3), bin(bitSlice('Hello', 3, 3));
|
||||||
|
select 4, 4, subString(bin('Hello'), 4, 4), bin(bitSlice('Hello', 4, 4));
|
||||||
|
select 5, 5, subString(bin('Hello'), 5, 5), bin(bitSlice('Hello', 5, 5));
|
||||||
|
select 6, 6, subString(bin('Hello'), 6, 6), bin(bitSlice('Hello', 6, 6));
|
||||||
|
select 7, 7, subString(bin('Hello'), 7, 7), bin(bitSlice('Hello', 7, 7));
|
||||||
|
select 8, 8, subString(bin('Hello'), 8, 8), bin(bitSlice('Hello', 8, 8));
|
||||||
|
select 9, 9, subString(bin('Hello'), 9, 9), bin(bitSlice('Hello', 9, 9));
|
||||||
|
select 10, 10, subString(bin('Hello'), 10, 10), bin(bitSlice('Hello', 10, 10));
|
||||||
|
select 11, 11, subString(bin('Hello'), 11, 11), bin(bitSlice('Hello', 11, 11));
|
||||||
|
select 12, 12, subString(bin('Hello'), 12, 12), bin(bitSlice('Hello', 12, 12));
|
||||||
|
select 13, 13, subString(bin('Hello'), 13, 13), bin(bitSlice('Hello', 13, 13));
|
||||||
|
select 14, 14, subString(bin('Hello'), 14, 14), bin(bitSlice('Hello', 14, 14));
|
||||||
|
select 15, 15, subString(bin('Hello'), 15, 15), bin(bitSlice('Hello', 15, 15));
|
||||||
|
select 16, 16, subString(bin('Hello'), 16, 16), bin(bitSlice('Hello', 16, 16));
|
||||||
|
|
||||||
|
select 1, -1, subString(bin('Hello'), 1, -1), bin(bitSlice('Hello', 1, -1));
|
||||||
|
select 2, -2, subString(bin('Hello'), 2, -2), bin(bitSlice('Hello', 2, -2));
|
||||||
|
select 3, -3, subString(bin('Hello'), 3, -3), bin(bitSlice('Hello', 3, -3));
|
||||||
|
select 4, -4, subString(bin('Hello'), 4, -4), bin(bitSlice('Hello', 4, -4));
|
||||||
|
select 5, -5, subString(bin('Hello'), 5, -5), bin(bitSlice('Hello', 5, -5));
|
||||||
|
select 6, -6, subString(bin('Hello'), 6, -6), bin(bitSlice('Hello', 6, -6));
|
||||||
|
select 7, -7, subString(bin('Hello'), 7, -7), bin(bitSlice('Hello', 7, -7));
|
||||||
|
select 8, -8, subString(bin('Hello'), 8, -8), bin(bitSlice('Hello', 8, -8));
|
||||||
|
select 9, -9, subString(bin('Hello'), 9, -9), bin(bitSlice('Hello', 9, -9));
|
||||||
|
select 10, -10, subString(bin('Hello'), 10, -10), bin(bitSlice('Hello', 10, -10));
|
||||||
|
select 11, -11, subString(bin('Hello'), 11, -11), bin(bitSlice('Hello', 11, -11));
|
||||||
|
select 12, -12, subString(bin('Hello'), 12, -12), bin(bitSlice('Hello', 12, -12));
|
||||||
|
select 13, -13, subString(bin('Hello'), 13, -13), bin(bitSlice('Hello', 13, -13));
|
||||||
|
select 14, -14, subString(bin('Hello'), 14, -14), bin(bitSlice('Hello', 14, -14));
|
||||||
|
select 15, -15, subString(bin('Hello'), 15, -15), bin(bitSlice('Hello', 15, -15));
|
||||||
|
select 16, -16, subString(bin('Hello'), 16, -16), bin(bitSlice('Hello', 16, -16));
|
||||||
|
|
||||||
|
select -1, 1, subString(bin('Hello'), -1, 1), bin(bitSlice('Hello', -1, 1));
|
||||||
|
select -2, 2, subString(bin('Hello'), -2, 2), bin(bitSlice('Hello', -2, 2));
|
||||||
|
select -3, 3, subString(bin('Hello'), -3, 3), bin(bitSlice('Hello', -3, 3));
|
||||||
|
select -4, 4, subString(bin('Hello'), -4, 4), bin(bitSlice('Hello', -4, 4));
|
||||||
|
select -5, 5, subString(bin('Hello'), -5, 5), bin(bitSlice('Hello', -5, 5));
|
||||||
|
select -6, 6, subString(bin('Hello'), -6, 6), bin(bitSlice('Hello', -6, 6));
|
||||||
|
select -7, 7, subString(bin('Hello'), -7, 7), bin(bitSlice('Hello', -7, 7));
|
||||||
|
select -8, 8, subString(bin('Hello'), -8, 8), bin(bitSlice('Hello', -8, 8));
|
||||||
|
select -9, 9, subString(bin('Hello'), -9, 9), bin(bitSlice('Hello', -9, 9));
|
||||||
|
select -10, 10, subString(bin('Hello'), -10, 10), bin(bitSlice('Hello', -10, 10));
|
||||||
|
select -11, 11, subString(bin('Hello'), -11, 11), bin(bitSlice('Hello', -11, 11));
|
||||||
|
select -12, 12, subString(bin('Hello'), -12, 12), bin(bitSlice('Hello', -12, 12));
|
||||||
|
select -13, 13, subString(bin('Hello'), -13, 13), bin(bitSlice('Hello', -13, 13));
|
||||||
|
select -14, 14, subString(bin('Hello'), -14, 14), bin(bitSlice('Hello', -14, 14));
|
||||||
|
select -15, 15, subString(bin('Hello'), -15, 15), bin(bitSlice('Hello', -15, 15));
|
||||||
|
select -16, 16, subString(bin('Hello'), -16, 16), bin(bitSlice('Hello', -16, 16));
|
||||||
|
|
||||||
|
select -1, -16, subString(bin('Hello'), -1, -16), bin(bitSlice('Hello', -1, -16));
|
||||||
|
select -2, -15, subString(bin('Hello'), -2, -15), bin(bitSlice('Hello', -2, -15));
|
||||||
|
select -3, -14, subString(bin('Hello'), -3, -14), bin(bitSlice('Hello', -3, -14));
|
||||||
|
select -4, -13, subString(bin('Hello'), -4, -13), bin(bitSlice('Hello', -4, -13));
|
||||||
|
select -5, -12, subString(bin('Hello'), -5, -12), bin(bitSlice('Hello', -5, -12));
|
||||||
|
select -6, -11, subString(bin('Hello'), -6, -11), bin(bitSlice('Hello', -6, -11));
|
||||||
|
select -7, -10, subString(bin('Hello'), -7, -10), bin(bitSlice('Hello', -7, -10));
|
||||||
|
select -8, -9, subString(bin('Hello'), -8, -9), bin(bitSlice('Hello', -8, -9));
|
||||||
|
select -9, -8, subString(bin('Hello'), -9, -8), bin(bitSlice('Hello', -9, -8));
|
||||||
|
select -10, -7, subString(bin('Hello'), -10, -7), bin(bitSlice('Hello', -10, -7));
|
||||||
|
select -11, -6, subString(bin('Hello'), -11, -6), bin(bitSlice('Hello', -11, -6));
|
||||||
|
select -12, -5, subString(bin('Hello'), -12, -5), bin(bitSlice('Hello', -12, -5));
|
||||||
|
select -13, -4, subString(bin('Hello'), -13, -4), bin(bitSlice('Hello', -13, -4));
|
||||||
|
select -14, -3, subString(bin('Hello'), -14, -3), bin(bitSlice('Hello', -14, -3));
|
||||||
|
select -15, -2, subString(bin('Hello'), -15, -2), bin(bitSlice('Hello', -15, -2));
|
||||||
|
select -16, -1, subString(bin('Hello'), -16, -1), bin(bitSlice('Hello', -16, -1));
|
||||||
|
|
||||||
|
select 'Dynamic Offset, Dynamic Length';
|
||||||
|
|
||||||
|
select number, number, subString(bin('Hello'), number, number), bin(bitSlice('Hello', number, number)) from numbers(16);
|
||||||
|
select number, -number, subString(bin('Hello'), number, -number), bin(bitSlice('Hello', number, -number)) from numbers(16);
|
||||||
|
select -number, -16+number, subString(bin('Hello'), -number, -16+number), bin(bitSlice('Hello', -number, -16+number)) from numbers(16);
|
||||||
|
select -number, number, subString(bin('Hello'), -number, number), bin(bitSlice('Hello', -number, number)) from numbers(16);
|
Loading…
Reference in New Issue
Block a user