Merge pull request #33360 from RogerYK/feat/bitSlice

This commit is contained in:
Vladimir C 2022-01-20 16:20:27 +03:00 committed by GitHub
commit 7156e64ee2
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 1258 additions and 0 deletions

View File

@ -117,6 +117,59 @@ Result:
## bitRotateRight(a, b) {#bitrotaterighta-b}
## bitSlice(s, offset, length)
Returns a substring starting with the bit from the offset index that is length bits long. bits indexing starts from
1
**Syntax**
``` sql
bitSlice(s, offset[, length])
```
**Arguments**
- `s` — s is [String](../../sql-reference/data-types/string.md)
or [FixedString](../../sql-reference/data-types/fixedstring.md).
- `offset` — The start index with bit, A positive value indicates an offset on the left, and a negative value is an
indent on the right. Numbering of the bits begins with 1.
- `length` — The length of substring with bit. If you specify a negative value, the function returns an open substring [
offset, array_length - length). If you omit the value, the function returns the substring [offset, the_end_string].
If length exceeds s, it will be truncate.If length isn't multiple of 8, will fill 0 on the right.
**Returned value**
- The substring. [String](../../sql-reference/data-types/string.md)
**Example**
Query:
``` sql
select bin('Hello'), bin(bitSlice('Hello', 1, 8))
select bin('Hello'), bin(bitSlice('Hello', 1, 2))
select bin('Hello'), bin(bitSlice('Hello', 1, 9))
select bin('Hello'), bin(bitSlice('Hello', -4, 8))
```
Result:
``` text
┌─bin('Hello')─────────────────────────────┬─bin(bitSlice('Hello', 1, 8))─┐
│ 0100100001100101011011000110110001101111 │ 01001000 │
└──────────────────────────────────────────┴──────────────────────────────┘
┌─bin('Hello')─────────────────────────────┬─bin(bitSlice('Hello', 1, 2))─┐
│ 0100100001100101011011000110110001101111 │ 01000000 │
└──────────────────────────────────────────┴──────────────────────────────┘
┌─bin('Hello')─────────────────────────────┬─bin(bitSlice('Hello', 1, 9))─┐
│ 0100100001100101011011000110110001101111 │ 0100100000000000 │
└──────────────────────────────────────────┴──────────────────────────────┘
┌─bin('Hello')─────────────────────────────┬─bin(bitSlice('Hello', -4, 8))─┐
│ 0100100001100101011011000110110001101111 │ 11110000 │
└──────────────────────────────────────────┴───────────────────────────────┘
```
## bitTest {#bittest}
Takes any integer and converts it into [binary form](https://en.wikipedia.org/wiki/Binary_number), returns the value of a bit at specified position. The countdown starts from 0 from the right to the left.

428
src/Functions/bitSlice.cpp Normal file
View File

@ -0,0 +1,428 @@
#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/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; }
bool useDefaultImplementationForConstants() 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;
std::optional<Int64> start_const;
std::optional<Int64> length_const;
if (const auto * column_start_const = checkAndGetColumn<ColumnConst>(column_start.get()))
{
start_const = column_start_const->getInt(0);
}
if (number_of_arguments == 3)
{
column_length = arguments[2].column;
if (const auto * column_length_const = checkAndGetColumn<ColumnConst>(column_length.get()))
length_const = column_length_const->getInt(0);
}
if (const ColumnString * col = checkAndGetColumn<ColumnString>(column_string.get()))
return executeForSource(column_start, column_length, start_const, length_const, StringSource(*col), input_rows_count);
else if (const ColumnFixedString * col_fixed = checkAndGetColumn<ColumnFixedString>(column_string.get()))
return executeForSource(
column_start, column_length, start_const, length_const, FixedStringSource(*col_fixed), input_rows_count);
else if (const ColumnConst * col_const = checkAndGetColumnConst<ColumnString>(column_string.get()))
return executeForSource(
column_start, column_length, start_const, length_const, 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, start_const, length_const, 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,
std::optional<Int64> start_const,
std::optional<Int64> length_const,
Source && source,
size_t input_rows_count) const
{
auto col_res = ColumnString::create();
if (!column_length)
{
if (start_const)
{
Int64 start_value = start_const.value();
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 (start_const && length_const)
{
Int64 start_value = start_const.value();
Int64 length_value = length_const.value();
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) // shift may eliminate 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; // offset_bit always represent left offset bit
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
{
while (!src.isEnd())
{
auto row_num = src.rowNum();
Int64 start = offset_column.getInt(row_num);
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; // offset_bit always represent left offset bit
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)) // begin and end are not in same byte OR there are gaps
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) // begin and end are in same byte AND there are no gaps
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; // offset_bit always represent left offset bit
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)) // begin and end are not in same byte OR there are gaps
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) // begin and end are in same byte AND there are no gaps
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
{
while (!src.isEnd())
{
size_t row_num = src.rowNum();
Int64 start = offset_column.getInt(row_num);
Int64 length = length_column.getInt(row_num);
if (start && length)
{
bool left_offset = start > 0;
size_t offset = left_offset ? static_cast<size_t>(start - 1) : -static_cast<size_t>(start);
size_t size = src.getElementSize();
size_t offset_byte;
size_t offset_bit;
size_t shift_bit;
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; // offset_bit always represent left offset bit
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;
size_t length_byte;
size_t over_bit;
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))) // begin and end are not in same byte OR there are gaps
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) // begin and end are in same byte AND there are no gaps
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>();
}
}

View File

@ -20,6 +20,7 @@ void registerFunctionBitXor(FunctionFactory & factory);
void registerFunctionBitNot(FunctionFactory & factory);
void registerFunctionBitShiftLeft(FunctionFactory & factory);
void registerFunctionBitShiftRight(FunctionFactory & factory);
void registerFunctionBitSlice(FunctionFactory & factory);
void registerFunctionBitRotateLeft(FunctionFactory & factory);
void registerFunctionBitRotateRight(FunctionFactory & factory);
void registerFunctionBitCount(FunctionFactory & factory);
@ -64,6 +65,7 @@ void registerFunctionsArithmetic(FunctionFactory & factory)
registerFunctionBitRotateLeft(factory);
registerFunctionBitRotateRight(factory);
registerFunctionBitCount(factory);
registerFunctionBitSlice(factory);
registerFunctionLeast(factory);
registerFunctionGreatest(factory);
registerFunctionBitTest(factory);

View File

@ -0,0 +1,244 @@
Const Offset
1 Hello\0 010010000110010101101100011011000110111100000000 010010000110010101101100011011000110111100000000
2 Hello\0 10010000110010101101100011011000110111100000000 100100001100101011011000110110001101111000000000
3 Hello\0 0010000110010101101100011011000110111100000000 001000011001010110110001101100011011110000000000
4 Hello\0 010000110010101101100011011000110111100000000 010000110010101101100011011000110111100000000000
5 Hello\0 10000110010101101100011011000110111100000000 100001100101011011000110110001101111000000000000
6 Hello\0 0000110010101101100011011000110111100000000 000011001010110110001101100011011110000000000000
7 Hello\0 000110010101101100011011000110111100000000 000110010101101100011011000110111100000000000000
8 Hello\0 00110010101101100011011000110111100000000 001100101011011000110110001101111000000000000000
9 Hello\0 0110010101101100011011000110111100000000 0110010101101100011011000110111100000000
10 Hello\0 110010101101100011011000110111100000000 1100101011011000110110001101111000000000
11 Hello\0 10010101101100011011000110111100000000 1001010110110001101100011011110000000000
12 Hello\0 0010101101100011011000110111100000000 0010101101100011011000110111100000000000
13 Hello\0 010101101100011011000110111100000000 0101011011000110110001101111000000000000
14 Hello\0 10101101100011011000110111100000000 1010110110001101100011011110000000000000
15 Hello\0 0101101100011011000110111100000000 0101101100011011000110111100000000000000
16 Hello\0 101101100011011000110111100000000 1011011000110110001101111000000000000000
-1 Hello\0 0 00000000
-2 Hello\0 00 00000000
-3 Hello\0 000 00000000
-4 Hello\0 0000 00000000
-5 Hello\0 00000 00000000
-6 Hello\0 000000 00000000
-7 Hello\0 0000000 00000000
-8 Hello\0 00000000 00000000
-9 Hello\0 100000000 1000000000000000
-10 Hello\0 1100000000 1100000000000000
-11 Hello\0 11100000000 1110000000000000
-12 Hello\0 111100000000 1111000000000000
-13 Hello\0 0111100000000 0111100000000000
-14 Hello\0 10111100000000 1011110000000000
-15 Hello\0 110111100000000 1101111000000000
-16 Hello\0 0110111100000000 0110111100000000
Const Truncate Offset
49 Hello\0
-49 Hello\0 010010000110010101101100011011000110111100000000 010010000110010101101100011011000110111100000000
Const Nullable Offset
1 \N \N \N
\N Hello\0 \N \N
\N \N \N \N
Const Offset, Const Length
1 1 Hello\0 0 00000000
2 2 Hello\0 10 10000000
3 3 Hello\0 001 00100000
4 4 Hello\0 0100 01000000
5 5 Hello\0 10000 10000000
6 6 Hello\0 000011 00001100
7 7 Hello\0 0001100 00011000
8 8 Hello\0 00110010 00110010
9 9 Hello\0 011001010 0110010100000000
10 10 Hello\0 1100101011 1100101011000000
11 11 Hello\0 10010101101 1001010110100000
12 12 Hello\0 001010110110 0010101101100000
13 13 Hello\0 0101011011000 0101011011000000
14 14 Hello\0 10101101100011 1010110110001100
15 15 Hello\0 010110110001101 0101101100011010
16 16 Hello\0 1011011000110110 1011011000110110
1 -1 Hello\0 01001000011001010110110001101100011011110000000 010010000110010101101100011011000110111100000000
2 -2 Hello\0 100100001100101011011000110110001101111000000 100100001100101011011000110110001101111000000000
3 -3 Hello\0 0010000110010101101100011011000110111100000 001000011001010110110001101100011011110000000000
4 -4 Hello\0 01000011001010110110001101100011011110000 010000110010101101100011011000110111100000000000
5 -5 Hello\0 100001100101011011000110110001101111000 1000011001010110110001101100011011110000
6 -6 Hello\0 0000110010101101100011011000110111100 0000110010101101100011011000110111100000
7 -7 Hello\0 00011001010110110001101100011011110 0001100101011011000110110001101111000000
8 -8 Hello\0 001100101011011000110110001101111 0011001010110110001101100011011110000000
9 -9 Hello\0 0110010101101100011011000110111 01100101011011000110110001101110
10 -10 Hello\0 11001010110110001101100011011 11001010110110001101100011011000
11 -11 Hello\0 100101011011000110110001101 10010101101100011011000110100000
12 -12 Hello\0 0010101101100011011000110 00101011011000110110001100000000
13 -13 Hello\0 01010110110001101100011 010101101100011011000110
14 -14 Hello\0 101011011000110110001 101011011000110110001000
15 -15 Hello\0 0101101100011011000 010110110001101100000000
16 -16 Hello\0 10110110001101100 101101100011011000000000
-1 1 Hello\0 0 00000000
-2 2 Hello\0 00 00000000
-3 3 Hello\0 000 00000000
-4 4 Hello\0 0000 00000000
-5 5 Hello\0 00000 00000000
-6 6 Hello\0 000000 00000000
-7 7 Hello\0 0000000 00000000
-8 8 Hello\0 00000000 00000000
-9 9 Hello\0 100000000 1000000000000000
-10 10 Hello\0 1100000000 1100000000000000
-11 11 Hello\0 11100000000 1110000000000000
-12 12 Hello\0 111100000000 1111000000000000
-13 13 Hello\0 0111100000000 0111100000000000
-14 14 Hello\0 10111100000000 1011110000000000
-15 15 Hello\0 110111100000000 1101111000000000
-16 16 Hello\0 0110111100000000 0110111100000000
-1 -16 Hello\0
-2 -15 Hello\0
-3 -14 Hello\0
-4 -13 Hello\0
-5 -12 Hello\0
-6 -11 Hello\0
-7 -10 Hello\0
-8 -9 Hello\0
-9 -8 Hello\0 1 10000000
-10 -7 Hello\0 110 11000000
-11 -6 Hello\0 11100 11100000
-12 -5 Hello\0 1111000 11110000
-13 -4 Hello\0 011110000 0111100000000000
-14 -3 Hello\0 10111100000 1011110000000000
-15 -2 Hello\0 1101111000000 1101111000000000
-16 -1 Hello\0 011011110000000 0110111100000000
Const Truncate Offset, Const Truncate Length
36 16 Hello\0 0111100000000 0111100000000000
49 1 Hello\0
-52 -44 Hello\0 0100 01000000
-49 -48 Hello\0
-49 49 Hello\0 010010000110010101101100011011000110111100000000 010010000110010101101100011011000110111100000000
Const Nullable Offset, Const Nullable Length
1 1 \N \N \N
\N 1 Hello\0 \N \N
1 \N Hello\0 \N \N
\N \N \N \N \N
Dynamic Offset, Dynamic Length
0 0 Hello\0
1 1 Hello\0 0 00000000
2 2 Hello\0 10 10000000
3 3 Hello\0 001 00100000
4 4 Hello\0 0100 01000000
5 5 Hello\0 10000 10000000
6 6 Hello\0 000011 00001100
7 7 Hello\0 0001100 00011000
8 8 Hello\0 00110010 00110010
9 9 Hello\0 011001010 0110010100000000
10 10 Hello\0 1100101011 1100101011000000
11 11 Hello\0 10010101101 1001010110100000
12 12 Hello\0 001010110110 0010101101100000
13 13 Hello\0 0101011011000 0101011011000000
14 14 Hello\0 10101101100011 1010110110001100
15 15 Hello\0 010110110001101 0101101100011010
0 0 Hello\0
1 -1 Hello\0 01001000011001010110110001101100011011110000000 010010000110010101101100011011000110111100000000
2 -2 Hello\0 100100001100101011011000110110001101111000000 100100001100101011011000110110001101111000000000
3 -3 Hello\0 0010000110010101101100011011000110111100000 001000011001010110110001101100011011110000000000
4 -4 Hello\0 01000011001010110110001101100011011110000 010000110010101101100011011000110111100000000000
5 -5 Hello\0 100001100101011011000110110001101111000 1000011001010110110001101100011011110000
6 -6 Hello\0 0000110010101101100011011000110111100 0000110010101101100011011000110111100000
7 -7 Hello\0 00011001010110110001101100011011110 0001100101011011000110110001101111000000
8 -8 Hello\0 001100101011011000110110001101111 0011001010110110001101100011011110000000
9 -9 Hello\0 0110010101101100011011000110111 01100101011011000110110001101110
10 -10 Hello\0 11001010110110001101100011011 11001010110110001101100011011000
11 -11 Hello\0 100101011011000110110001101 10010101101100011011000110100000
12 -12 Hello\0 0010101101100011011000110 00101011011000110110001100000000
13 -13 Hello\0 01010110110001101100011 010101101100011011000110
14 -14 Hello\0 101011011000110110001 101011011000110110001000
15 -15 Hello\0 0101101100011011000 010110110001101100000000
0 -16 Hello\0
-1 -15 Hello\0
-2 -14 Hello\0
-3 -13 Hello\0
-4 -12 Hello\0
-5 -11 Hello\0
-6 -10 Hello\0
-7 -9 Hello\0
-8 -8 Hello\0
-9 -7 Hello\0 10 10000000
-10 -6 Hello\0 1100 11000000
-11 -5 Hello\0 111000 11100000
-12 -4 Hello\0 11110000 11110000
-13 -3 Hello\0 0111100000 0111100000000000
-14 -2 Hello\0 101111000000 1011110000000000
-15 -1 Hello\0 11011110000000 1101111000000000
0 0 Hello\0
-1 1 Hello\0 0 00000000
-2 2 Hello\0 00 00000000
-3 3 Hello\0 000 00000000
-4 4 Hello\0 0000 00000000
-5 5 Hello\0 00000 00000000
-6 6 Hello\0 000000 00000000
-7 7 Hello\0 0000000 00000000
-8 8 Hello\0 00000000 00000000
-9 9 Hello\0 100000000 1000000000000000
-10 10 Hello\0 1100000000 1100000000000000
-11 11 Hello\0 11100000000 1110000000000000
-12 12 Hello\0 111100000000 1111000000000000
-13 13 Hello\0 0111100000000 0111100000000000
-14 14 Hello\0 10111100000000 1011110000000000
-15 15 Hello\0 110111100000000 1101111000000000
Dynamic Truncate Offset, Dynamic Truncate Length
-8 8 Hello\0 00000000 00000000
-7 8 Hello\0 0000000 00000000
-6 8 Hello\0 000000 00000000
-5 8 Hello\0 00000 00000000
-4 8 Hello\0 0000 00000000
-3 8 Hello\0 000 00000000
-2 8 Hello\0 00 00000000
-1 8 Hello\0 0 00000000
0 8 Hello\0
-4 0 Hello\0
-4 1 Hello\0 0 00000000
-4 2 Hello\0 00 00000000
-4 3 Hello\0 000 00000000
-4 4 Hello\0 0000 00000000
-4 5 Hello\0 0000 00000000
-4 6 Hello\0 0000 00000000
-4 7 Hello\0 0000 00000000
-4 8 Hello\0 0000 00000000
-44 8 Hello\0 10000110 10000110
-45 8 Hello\0 01000011 01000011
-46 8 Hello\0 00100001 00100001
-47 8 Hello\0 10010000 10010000
-48 8 Hello\0 01001000 01001000
-49 8 Hello\0 0100100 01001000
-50 8 Hello\0 010010 01001000
-51 8 Hello\0 01001 01001000
-52 8 Hello\0 0100 01000000
-52 0 Hello\0
-52 1 Hello\0
-52 2 Hello\0
-52 3 Hello\0
-52 4 Hello\0
-52 5 Hello\0 0 00000000
-52 6 Hello\0 01 01000000
-52 7 Hello\0 010 01000000
-52 8 Hello\0 0100 01000000
-52 48 Hello\0 01001000011001010110110001101100011011110000 010010000110010101101100011011000110111100000000
-52 49 Hello\0 010010000110010101101100011011000110111100000 010010000110010101101100011011000110111100000000
-52 50 Hello\0 0100100001100101011011000110110001101111000000 010010000110010101101100011011000110111100000000
-52 51 Hello\0 01001000011001010110110001101100011011110000000 010010000110010101101100011011000110111100000000
-52 52 Hello\0 010010000110010101101100011011000110111100000000 010010000110010101101100011011000110111100000000
-52 53 Hello\0 010010000110010101101100011011000110111100000000 010010000110010101101100011011000110111100000000
-52 54 Hello\0 010010000110010101101100011011000110111100000000 010010000110010101101100011011000110111100000000
-52 55 Hello\0 010010000110010101101100011011000110111100000000 010010000110010101101100011011000110111100000000
-52 56 Hello\0 010010000110010101101100011011000110111100000000 010010000110010101101100011011000110111100000000
Dynamic Nullable Offset, Dynamic Nullable Length
0 0 Hello\0
\N 1 Hello\0 \N \N
2 \N Hello\0 \N \N
3 3 \N \N \N
4 4 Hello\0 0100 01000000
\N 5 Hello\0 \N \N
6 \N Hello\0 \N \N
\N \N \N \N \N
8 8 Hello\0 00110010 00110010
\N 9 Hello\0 \N \N
10 \N Hello\0 \N \N
11 11 \N \N \N
12 12 Hello\0 001010110110 0010101101100000
\N 13 Hello\0 \N \N
14 \N Hello\0 \N \N
\N \N \N \N \N

View File

@ -0,0 +1,143 @@
SELECT 'Const Offset';
select 1 as offset, toFixedString('Hello', 6) as s, subString(bin(s), offset), bin(bitSlice(s, offset));
select 2 as offset, toFixedString('Hello', 6) as s, subString(bin(s), offset), bin(bitSlice(s, offset));
select 3 as offset, toFixedString('Hello', 6) as s, subString(bin(s), offset), bin(bitSlice(s, offset));
select 4 as offset, toFixedString('Hello', 6) as s, subString(bin(s), offset), bin(bitSlice(s, offset));
select 5 as offset, toFixedString('Hello', 6) as s, subString(bin(s), offset), bin(bitSlice(s, offset));
select 6 as offset, toFixedString('Hello', 6) as s, subString(bin(s), offset), bin(bitSlice(s, offset));
select 7 as offset, toFixedString('Hello', 6) as s, subString(bin(s), offset), bin(bitSlice(s, offset));
select 8 as offset, toFixedString('Hello', 6) as s, subString(bin(s), offset), bin(bitSlice(s, offset));
select 9 as offset, toFixedString('Hello', 6) as s, subString(bin(s), offset), bin(bitSlice(s, offset));
select 10 as offset, toFixedString('Hello', 6) as s, subString(bin(s), offset), bin(bitSlice(s, offset));
select 11 as offset, toFixedString('Hello', 6) as s, subString(bin(s), offset), bin(bitSlice(s, offset));
select 12 as offset, toFixedString('Hello', 6) as s, subString(bin(s), offset), bin(bitSlice(s, offset));
select 13 as offset, toFixedString('Hello', 6) as s, subString(bin(s), offset), bin(bitSlice(s, offset));
select 14 as offset, toFixedString('Hello', 6) as s, subString(bin(s), offset), bin(bitSlice(s, offset));
select 15 as offset, toFixedString('Hello', 6) as s, subString(bin(s), offset), bin(bitSlice(s, offset));
select 16 as offset, toFixedString('Hello', 6) as s, subString(bin(s), offset), bin(bitSlice(s, offset));
select -1 as offset, toFixedString('Hello', 6) as s, subString(bin(s), offset), bin(bitSlice(s, offset));
select -2 as offset, toFixedString('Hello', 6) as s, subString(bin(s), offset), bin(bitSlice(s, offset));
select -3 as offset, toFixedString('Hello', 6) as s, subString(bin(s), offset), bin(bitSlice(s, offset));
select -4 as offset, toFixedString('Hello', 6) as s, subString(bin(s), offset), bin(bitSlice(s, offset));
select -5 as offset, toFixedString('Hello', 6) as s, subString(bin(s), offset), bin(bitSlice(s, offset));
select -6 as offset, toFixedString('Hello', 6) as s, subString(bin(s), offset), bin(bitSlice(s, offset));
select -7 as offset, toFixedString('Hello', 6) as s, subString(bin(s), offset), bin(bitSlice(s, offset));
select -8 as offset, toFixedString('Hello', 6) as s, subString(bin(s), offset), bin(bitSlice(s, offset));
select -9 as offset, toFixedString('Hello', 6) as s, subString(bin(s), offset), bin(bitSlice(s, offset));
select -10 as offset, toFixedString('Hello', 6) as s, subString(bin(s), offset), bin(bitSlice(s, offset));
select -11 as offset, toFixedString('Hello', 6) as s, subString(bin(s), offset), bin(bitSlice(s, offset));
select -12 as offset, toFixedString('Hello', 6) as s, subString(bin(s), offset), bin(bitSlice(s, offset));
select -13 as offset, toFixedString('Hello', 6) as s, subString(bin(s), offset), bin(bitSlice(s, offset));
select -14 as offset, toFixedString('Hello', 6) as s, subString(bin(s), offset), bin(bitSlice(s, offset));
select -15 as offset, toFixedString('Hello', 6) as s, subString(bin(s), offset), bin(bitSlice(s, offset));
select -16 as offset, toFixedString('Hello', 6) as s, subString(bin(s), offset), bin(bitSlice(s, offset));
SELECT 'Const Truncate Offset';
select 49 as offset, toFixedString('Hello', 6) as s, subString(bin(s), offset), bin(bitSlice(s, offset));
select -49 as offset, toFixedString('Hello', 6) as s, subString(bin(s), offset), bin(bitSlice(s, offset));
SELECT 'Const Nullable Offset';
select 1 as offset, null as s, subString(bin(s), offset), bin(bitSlice(s, offset));
select null as offset, toFixedString('Hello', 6) as s, subString(bin(s), offset), bin(bitSlice(s, offset));
select null as offset, null as s, subString(bin(s), offset), bin(bitSlice(s, offset));
SELECT 'Const Offset, Const Length';
select 1 as offset, 1 as length, toFixedString('Hello', 6) as s, subString(bin(s), offset, length), bin(bitSlice(s, offset, length));
select 2 as offset, 2 as length, toFixedString('Hello', 6) as s, subString(bin(s), offset, length), bin(bitSlice(s, offset, length));
select 3 as offset, 3 as length, toFixedString('Hello', 6) as s, subString(bin(s), offset, length), bin(bitSlice(s, offset, length));
select 4 as offset, 4 as length, toFixedString('Hello', 6) as s, subString(bin(s), offset, length), bin(bitSlice(s, offset, length));
select 5 as offset, 5 as length, toFixedString('Hello', 6) as s, subString(bin(s), offset, length), bin(bitSlice(s, offset, length));
select 6 as offset, 6 as length, toFixedString('Hello', 6) as s, subString(bin(s), offset, length), bin(bitSlice(s, offset, length));
select 7 as offset, 7 as length, toFixedString('Hello', 6) as s, subString(bin(s), offset, length), bin(bitSlice(s, offset, length));
select 8 as offset, 8 as length, toFixedString('Hello', 6) as s, subString(bin(s), offset, length), bin(bitSlice(s, offset, length));
select 9 as offset, 9 as length, toFixedString('Hello', 6) as s, subString(bin(s), offset, length), bin(bitSlice(s, offset, length));
select 10 as offset, 10 as length, toFixedString('Hello', 6) as s, subString(bin(s), offset, length), bin(bitSlice(s, offset, length));
select 11 as offset, 11 as length, toFixedString('Hello', 6) as s, subString(bin(s), offset, length), bin(bitSlice(s, offset, length));
select 12 as offset, 12 as length, toFixedString('Hello', 6) as s, subString(bin(s), offset, length), bin(bitSlice(s, offset, length));
select 13 as offset, 13 as length, toFixedString('Hello', 6) as s, subString(bin(s), offset, length), bin(bitSlice(s, offset, length));
select 14 as offset, 14 as length, toFixedString('Hello', 6) as s, subString(bin(s), offset, length), bin(bitSlice(s, offset, length));
select 15 as offset, 15 as length, toFixedString('Hello', 6) as s, subString(bin(s), offset, length), bin(bitSlice(s, offset, length));
select 16 as offset, 16 as length, toFixedString('Hello', 6) as s, subString(bin(s), offset, length), bin(bitSlice(s, offset, length));
select 1 as offset, -1 as length, toFixedString('Hello', 6) as s, subString(bin(s), offset, length), bin(bitSlice(s, offset, length));
select 2 as offset, -2 as length, toFixedString('Hello', 6) as s, subString(bin(s), offset, length), bin(bitSlice(s, offset, length));
select 3 as offset, -3 as length, toFixedString('Hello', 6) as s, subString(bin(s), offset, length), bin(bitSlice(s, offset, length));
select 4 as offset, -4 as length, toFixedString('Hello', 6) as s, subString(bin(s), offset, length), bin(bitSlice(s, offset, length));
select 5 as offset, -5 as length, toFixedString('Hello', 6) as s, subString(bin(s), offset, length), bin(bitSlice(s, offset, length));
select 6 as offset, -6 as length, toFixedString('Hello', 6) as s, subString(bin(s), offset, length), bin(bitSlice(s, offset, length));
select 7 as offset, -7 as length, toFixedString('Hello', 6) as s, subString(bin(s), offset, length), bin(bitSlice(s, offset, length));
select 8 as offset, -8 as length, toFixedString('Hello', 6) as s, subString(bin(s), offset, length), bin(bitSlice(s, offset, length));
select 9 as offset, -9 as length, toFixedString('Hello', 6) as s, subString(bin(s), offset, length), bin(bitSlice(s, offset, length));
select 10 as offset, -10 as length, toFixedString('Hello', 6) as s, subString(bin(s), offset, length), bin(bitSlice(s, offset, length));
select 11 as offset, -11 as length, toFixedString('Hello', 6) as s, subString(bin(s), offset, length), bin(bitSlice(s, offset, length));
select 12 as offset, -12 as length, toFixedString('Hello', 6) as s, subString(bin(s), offset, length), bin(bitSlice(s, offset, length));
select 13 as offset, -13 as length, toFixedString('Hello', 6) as s, subString(bin(s), offset, length), bin(bitSlice(s, offset, length));
select 14 as offset, -14 as length, toFixedString('Hello', 6) as s, subString(bin(s), offset, length), bin(bitSlice(s, offset, length));
select 15 as offset, -15 as length, toFixedString('Hello', 6) as s, subString(bin(s), offset, length), bin(bitSlice(s, offset, length));
select 16 as offset, -16 as length, toFixedString('Hello', 6) as s, subString(bin(s), offset, length), bin(bitSlice(s, offset, length));
select -1 as offset, 1 as length, toFixedString('Hello', 6) as s, subString(bin(s), offset, length), bin(bitSlice(s, offset, length));
select -2 as offset, 2 as length, toFixedString('Hello', 6) as s, subString(bin(s), offset, length), bin(bitSlice(s, offset, length));
select -3 as offset, 3 as length, toFixedString('Hello', 6) as s, subString(bin(s), offset, length), bin(bitSlice(s, offset, length));
select -4 as offset, 4 as length, toFixedString('Hello', 6) as s, subString(bin(s), offset, length), bin(bitSlice(s, offset, length));
select -5 as offset, 5 as length, toFixedString('Hello', 6) as s, subString(bin(s), offset, length), bin(bitSlice(s, offset, length));
select -6 as offset, 6 as length, toFixedString('Hello', 6) as s, subString(bin(s), offset, length), bin(bitSlice(s, offset, length));
select -7 as offset, 7 as length, toFixedString('Hello', 6) as s, subString(bin(s), offset, length), bin(bitSlice(s, offset, length));
select -8 as offset, 8 as length, toFixedString('Hello', 6) as s, subString(bin(s), offset, length), bin(bitSlice(s, offset, length));
select -9 as offset, 9 as length, toFixedString('Hello', 6) as s, subString(bin(s), offset, length), bin(bitSlice(s, offset, length));
select -10 as offset, 10 as length, toFixedString('Hello', 6) as s, subString(bin(s), offset, length), bin(bitSlice(s, offset, length));
select -11 as offset, 11 as length, toFixedString('Hello', 6) as s, subString(bin(s), offset, length), bin(bitSlice(s, offset, length));
select -12 as offset, 12 as length, toFixedString('Hello', 6) as s, subString(bin(s), offset, length), bin(bitSlice(s, offset, length));
select -13 as offset, 13 as length, toFixedString('Hello', 6) as s, subString(bin(s), offset, length), bin(bitSlice(s, offset, length));
select -14 as offset, 14 as length, toFixedString('Hello', 6) as s, subString(bin(s), offset, length), bin(bitSlice(s, offset, length));
select -15 as offset, 15 as length, toFixedString('Hello', 6) as s, subString(bin(s), offset, length), bin(bitSlice(s, offset, length));
select -16 as offset, 16 as length, toFixedString('Hello', 6) as s, subString(bin(s), offset, length), bin(bitSlice(s, offset, length));
select -1 as offset, -16 as length, toFixedString('Hello', 6) as s, subString(bin(s), offset, length), bin(bitSlice(s, offset, length));
select -2 as offset, -15 as length, toFixedString('Hello', 6) as s, subString(bin(s), offset, length), bin(bitSlice(s, offset, length));
select -3 as offset, -14 as length, toFixedString('Hello', 6) as s, subString(bin(s), offset, length), bin(bitSlice(s, offset, length));
select -4 as offset, -13 as length, toFixedString('Hello', 6) as s, subString(bin(s), offset, length), bin(bitSlice(s, offset, length));
select -5 as offset, -12 as length, toFixedString('Hello', 6) as s, subString(bin(s), offset, length), bin(bitSlice(s, offset, length));
select -6 as offset, -11 as length, toFixedString('Hello', 6) as s, subString(bin(s), offset, length), bin(bitSlice(s, offset, length));
select -7 as offset, -10 as length, toFixedString('Hello', 6) as s, subString(bin(s), offset, length), bin(bitSlice(s, offset, length));
select -8 as offset, -9 as length, toFixedString('Hello', 6) as s, subString(bin(s), offset, length), bin(bitSlice(s, offset, length));
select -9 as offset, -8 as length, toFixedString('Hello', 6) as s, subString(bin(s), offset, length), bin(bitSlice(s, offset, length));
select -10 as offset, -7 as length, toFixedString('Hello', 6) as s, subString(bin(s), offset, length), bin(bitSlice(s, offset, length));
select -11 as offset, -6 as length, toFixedString('Hello', 6) as s, subString(bin(s), offset, length), bin(bitSlice(s, offset, length));
select -12 as offset, -5 as length, toFixedString('Hello', 6) as s, subString(bin(s), offset, length), bin(bitSlice(s, offset, length));
select -13 as offset, -4 as length, toFixedString('Hello', 6) as s, subString(bin(s), offset, length), bin(bitSlice(s, offset, length));
select -14 as offset, -3 as length, toFixedString('Hello', 6) as s, subString(bin(s), offset, length), bin(bitSlice(s, offset, length));
select -15 as offset, -2 as length, toFixedString('Hello', 6) as s, subString(bin(s), offset, length), bin(bitSlice(s, offset, length));
select -16 as offset, -1 as length, toFixedString('Hello', 6) as s, subString(bin(s), offset, length), bin(bitSlice(s, offset, length));
select 'Const Truncate Offset, Const Truncate Length';
select 36 as offset, 16 as length, toFixedString('Hello', 6) as s, subString(bin(s), offset, length), bin(bitSlice(s, offset, length));
select 49 as offset, 1 as length, toFixedString('Hello', 6) as s, subString(bin(s), offset, length), bin(bitSlice(s, offset, length));
select -52 as offset, -44 as length, toFixedString('Hello', 6) as s, subString(bin(s), offset, length), bin(bitSlice(s, offset, length));
select -49 as offset, -48 as length, toFixedString('Hello', 6) as s, subString(bin(s), offset, length), bin(bitSlice(s, offset, length));
select -49 as offset, 49 as length, toFixedString('Hello', 6) as s, subString(bin(s), offset, length), bin(bitSlice(s, offset, length));
select 'Const Nullable Offset, Const Nullable Length';
select 1 as offset, 1 as length, null as s, subString(bin(s), offset , length), bin(bitSlice(s, offset, length));
select null as offset, 1 as length, toFixedString('Hello', 6) as s, subString(bin(s), offset, length), bin(bitSlice(s, offset, length));
select 1 as offset, null as length, toFixedString('Hello', 6) as s, subString(bin(s), offset , length), bin(bitSlice(s, offset, length));
select null as offset, null as length, null as s, subString(bin(s), offset , length), bin(bitSlice(s, offset, length));
select 'Dynamic Offset, Dynamic Length';
select number as offset, number as length, toFixedString('Hello', 6) as s, subString(bin(s), offset , length), bin(bitSlice(s, offset, length)) from numbers(16);
select number as offset, -number as length, toFixedString('Hello', 6) as s, subString(bin(s), offset , length), bin(bitSlice(s, offset, length)) from numbers(16);
select -number as offset, -16+number as length, toFixedString('Hello', 6) as s, subString(bin(s), offset , length), bin(bitSlice(s, offset, length)) from numbers(16);
select -number as offset, number as length, toFixedString('Hello', 6) as s, subString(bin(s), offset , length), bin(bitSlice(s, offset, length)) from numbers(16);
select 'Dynamic Truncate Offset, Dynamic Truncate Length';
select number-8 as offset, 8 as length, toFixedString('Hello', 6) as s, subString(bin(s), offset , length), bin(bitSlice(s, offset, length)) from numbers(9);
select -4 as offset, number as length, toFixedString('Hello', 6) as s, subString(bin(s), offset , length), bin(bitSlice(s, offset, length)) from numbers(9);
select -44-number as offset, 8 as length, toFixedString('Hello', 6) as s, subString(bin(s), offset , length), bin(bitSlice(s, offset, length)) from numbers(9);
select -52 as offset, number as length, toFixedString('Hello', 6) as s, subString(bin(s), offset , length), bin(bitSlice(s, offset, length)) from numbers(9);
select -52 as offset, number + 48 as length, toFixedString('Hello', 6) as s, subString(bin(s), offset , length), bin(bitSlice(s, offset, length)) from numbers(9);
select 'Dynamic Nullable Offset, Dynamic Nullable Length';
select if(number%4 ==1 or number%8==7, null, number) as offset, if(number%4==2 or number%8==7, null, number) as length,if(number%4 ==3, null, toFixedString('Hello', 6)) as s,
subString(bin(s), offset, length), bin(bitSlice(s, offset , length))
from numbers(16);

View File

@ -0,0 +1,244 @@
Const Offset
1 Hello 0100100001100101011011000110110001101111 0100100001100101011011000110110001101111
2 Hello 100100001100101011011000110110001101111 1001000011001010110110001101100011011110
3 Hello 00100001100101011011000110110001101111 0010000110010101101100011011000110111100
4 Hello 0100001100101011011000110110001101111 0100001100101011011000110110001101111000
5 Hello 100001100101011011000110110001101111 1000011001010110110001101100011011110000
6 Hello 00001100101011011000110110001101111 0000110010101101100011011000110111100000
7 Hello 0001100101011011000110110001101111 0001100101011011000110110001101111000000
8 Hello 001100101011011000110110001101111 0011001010110110001101100011011110000000
9 Hello 01100101011011000110110001101111 01100101011011000110110001101111
10 Hello 1100101011011000110110001101111 11001010110110001101100011011110
11 Hello 100101011011000110110001101111 10010101101100011011000110111100
12 Hello 00101011011000110110001101111 00101011011000110110001101111000
13 Hello 0101011011000110110001101111 01010110110001101100011011110000
14 Hello 101011011000110110001101111 10101101100011011000110111100000
15 Hello 01011011000110110001101111 01011011000110110001101111000000
16 Hello 1011011000110110001101111 10110110001101100011011110000000
-1 Hello 1 10000000
-2 Hello 11 11000000
-3 Hello 111 11100000
-4 Hello 1111 11110000
-5 Hello 01111 01111000
-6 Hello 101111 10111100
-7 Hello 1101111 11011110
-8 Hello 01101111 01101111
-9 Hello 001101111 0011011110000000
-10 Hello 0001101111 0001101111000000
-11 Hello 10001101111 1000110111100000
-12 Hello 110001101111 1100011011110000
-13 Hello 0110001101111 0110001101111000
-14 Hello 10110001101111 1011000110111100
-15 Hello 110110001101111 1101100011011110
-16 Hello 0110110001101111 0110110001101111
Const Truncate Offset
41 Hello
-41 Hello 0100100001100101011011000110110001101111 0100100001100101011011000110110001101111
Const Nullable Offset
1 \N \N \N
\N Hello \N \N
\N \N \N \N
Const Offset, Const Length
1 1 Hello 0 00000000
2 2 Hello 10 10000000
3 3 Hello 001 00100000
4 4 Hello 0100 01000000
5 5 Hello 10000 10000000
6 6 Hello 000011 00001100
7 7 Hello 0001100 00011000
8 8 Hello 00110010 00110010
9 9 Hello 011001010 0110010100000000
10 10 Hello 1100101011 1100101011000000
11 11 Hello 10010101101 1001010110100000
12 12 Hello 001010110110 0010101101100000
13 13 Hello 0101011011000 0101011011000000
14 14 Hello 10101101100011 1010110110001100
15 15 Hello 010110110001101 0101101100011010
16 16 Hello 1011011000110110 1011011000110110
1 -1 Hello 010010000110010101101100011011000110111 0100100001100101011011000110110001101110
2 -2 Hello 1001000011001010110110001101100011011 1001000011001010110110001101100011011000
3 -3 Hello 00100001100101011011000110110001101 0010000110010101101100011011000110100000
4 -4 Hello 010000110010101101100011011000110 0100001100101011011000110110001100000000
5 -5 Hello 1000011001010110110001101100011 10000110010101101100011011000110
6 -6 Hello 00001100101011011000110110001 00001100101011011000110110001000
7 -7 Hello 000110010101101100011011000 00011001010110110001101100000000
8 -8 Hello 0011001010110110001101100 00110010101101100011011000000000
9 -9 Hello 01100101011011000110110 011001010110110001101100
10 -10 Hello 110010101101100011011 110010101101100011011000
11 -11 Hello 1001010110110001101 100101011011000110100000
12 -12 Hello 00101011011000110 001010110110001100000000
13 -13 Hello 010101101100011 0101011011000110
14 -14 Hello 1010110110001 1010110110001000
15 -15 Hello 01011011000 0101101100000000
16 -16 Hello 101101100 1011011000000000
-1 1 Hello 1 10000000
-2 2 Hello 11 11000000
-3 3 Hello 111 11100000
-4 4 Hello 1111 11110000
-5 5 Hello 01111 01111000
-6 6 Hello 101111 10111100
-7 7 Hello 1101111 11011110
-8 8 Hello 01101111 01101111
-9 9 Hello 001101111 0011011110000000
-10 10 Hello 0001101111 0001101111000000
-11 11 Hello 10001101111 1000110111100000
-12 12 Hello 110001101111 1100011011110000
-13 13 Hello 0110001101111 0110001101111000
-14 14 Hello 10110001101111 1011000110111100
-15 15 Hello 110110001101111 1101100011011110
-16 16 Hello 0110110001101111 0110110001101111
-1 -16 Hello
-2 -15 Hello
-3 -14 Hello
-4 -13 Hello
-5 -12 Hello
-6 -11 Hello
-7 -10 Hello
-8 -9 Hello
-9 -8 Hello 0 00000000
-10 -7 Hello 000 00000000
-11 -6 Hello 10001 10001000
-12 -5 Hello 1100011 11000110
-13 -4 Hello 011000110 0110001100000000
-14 -3 Hello 10110001101 1011000110100000
-15 -2 Hello 1101100011011 1101100011011000
-16 -1 Hello 011011000110111 0110110001101110
Const Truncate Offset, Const Truncate Length
36 8 Hello 01111 01111000
41 1 Hello
-44 -36 Hello 0100 01000000
-41 -40 Hello
-41 41 Hello 0100100001100101011011000110110001101111 0100100001100101011011000110110001101111
Const Nullable Offset, Const Nullable Length
1 1 \N \N \N
\N 1 Hello \N \N
1 \N Hello \N \N
\N \N \N \N \N
Dynamic Offset, Dynamic Length
0 0 Hello
1 1 Hello 0 00000000
2 2 Hello 10 10000000
3 3 Hello 001 00100000
4 4 Hello 0100 01000000
5 5 Hello 10000 10000000
6 6 Hello 000011 00001100
7 7 Hello 0001100 00011000
8 8 Hello 00110010 00110010
9 9 Hello 011001010 0110010100000000
10 10 Hello 1100101011 1100101011000000
11 11 Hello 10010101101 1001010110100000
12 12 Hello 001010110110 0010101101100000
13 13 Hello 0101011011000 0101011011000000
14 14 Hello 10101101100011 1010110110001100
15 15 Hello 010110110001101 0101101100011010
0 0 Hello
1 -1 Hello 010010000110010101101100011011000110111 0100100001100101011011000110110001101110
2 -2 Hello 1001000011001010110110001101100011011 1001000011001010110110001101100011011000
3 -3 Hello 00100001100101011011000110110001101 0010000110010101101100011011000110100000
4 -4 Hello 010000110010101101100011011000110 0100001100101011011000110110001100000000
5 -5 Hello 1000011001010110110001101100011 10000110010101101100011011000110
6 -6 Hello 00001100101011011000110110001 00001100101011011000110110001000
7 -7 Hello 000110010101101100011011000 00011001010110110001101100000000
8 -8 Hello 0011001010110110001101100 00110010101101100011011000000000
9 -9 Hello 01100101011011000110110 011001010110110001101100
10 -10 Hello 110010101101100011011 110010101101100011011000
11 -11 Hello 1001010110110001101 100101011011000110100000
12 -12 Hello 00101011011000110 001010110110001100000000
13 -13 Hello 010101101100011 0101011011000110
14 -14 Hello 1010110110001 1010110110001000
15 -15 Hello 01011011000 0101101100000000
0 -16 Hello
-1 -15 Hello
-2 -14 Hello
-3 -13 Hello
-4 -12 Hello
-5 -11 Hello
-6 -10 Hello
-7 -9 Hello
-8 -8 Hello
-9 -7 Hello 00 00000000
-10 -6 Hello 0001 00010000
-11 -5 Hello 100011 10001100
-12 -4 Hello 11000110 11000110
-13 -3 Hello 0110001101 0110001101000000
-14 -2 Hello 101100011011 1011000110110000
-15 -1 Hello 11011000110111 1101100011011100
0 0 Hello
-1 1 Hello 1 10000000
-2 2 Hello 11 11000000
-3 3 Hello 111 11100000
-4 4 Hello 1111 11110000
-5 5 Hello 01111 01111000
-6 6 Hello 101111 10111100
-7 7 Hello 1101111 11011110
-8 8 Hello 01101111 01101111
-9 9 Hello 001101111 0011011110000000
-10 10 Hello 0001101111 0001101111000000
-11 11 Hello 10001101111 1000110111100000
-12 12 Hello 110001101111 1100011011110000
-13 13 Hello 0110001101111 0110001101111000
-14 14 Hello 10110001101111 1011000110111100
-15 15 Hello 110110001101111 1101100011011110
Dynamic Truncate Offset, Dynamic Truncate Length
-8 8 Hello 01101111 01101111
-7 8 Hello 1101111 11011110
-6 8 Hello 101111 10111100
-5 8 Hello 01111 01111000
-4 8 Hello 1111 11110000
-3 8 Hello 111 11100000
-2 8 Hello 11 11000000
-1 8 Hello 1 10000000
0 8 Hello
-4 0 Hello
-4 1 Hello 1 10000000
-4 2 Hello 11 11000000
-4 3 Hello 111 11100000
-4 4 Hello 1111 11110000
-4 5 Hello 1111 11110000
-4 6 Hello 1111 11110000
-4 7 Hello 1111 11110000
-4 8 Hello 1111 11110000
-36 8 Hello 10000110 10000110
-37 8 Hello 01000011 01000011
-38 8 Hello 00100001 00100001
-39 8 Hello 10010000 10010000
-40 8 Hello 01001000 01001000
-41 8 Hello 0100100 01001000
-42 8 Hello 010010 01001000
-43 8 Hello 01001 01001000
-44 8 Hello 0100 01000000
-44 0 Hello
-44 1 Hello
-44 2 Hello
-44 3 Hello
-44 4 Hello
-44 5 Hello 0 00000000
-44 6 Hello 01 01000000
-44 7 Hello 010 01000000
-44 8 Hello 0100 01000000
-44 40 Hello 010010000110010101101100011011000110 0100100001100101011011000110110001100000
-44 41 Hello 0100100001100101011011000110110001101 0100100001100101011011000110110001101000
-44 42 Hello 01001000011001010110110001101100011011 0100100001100101011011000110110001101100
-44 43 Hello 010010000110010101101100011011000110111 0100100001100101011011000110110001101110
-44 44 Hello 0100100001100101011011000110110001101111 0100100001100101011011000110110001101111
-44 45 Hello 0100100001100101011011000110110001101111 0100100001100101011011000110110001101111
-44 46 Hello 0100100001100101011011000110110001101111 0100100001100101011011000110110001101111
-44 47 Hello 0100100001100101011011000110110001101111 0100100001100101011011000110110001101111
-44 48 Hello 0100100001100101011011000110110001101111 0100100001100101011011000110110001101111
Dynamic Nullable Offset, Dynamic Nullable Length
0 0 Hello
\N 1 Hello \N \N
2 \N Hello \N \N
3 3 \N \N \N
4 4 Hello 0100 01000000
\N 5 Hello \N \N
6 \N Hello \N \N
\N \N \N \N \N
8 8 Hello 00110010 00110010
\N 9 Hello \N \N
10 \N Hello \N \N
11 11 \N \N \N
12 12 Hello 001010110110 0010101101100000
\N 13 Hello \N \N
14 \N Hello \N \N
\N \N \N \N \N

View File

@ -0,0 +1,144 @@
SELECT 'Const Offset';
select 1 as offset, 'Hello' as s, subString(bin(s), offset), bin(bitSlice(s, offset));
select 2 as offset, 'Hello' as s, subString(bin(s), offset), bin(bitSlice(s, offset));
select 3 as offset, 'Hello' as s, subString(bin(s), offset), bin(bitSlice(s, offset));
select 4 as offset, 'Hello' as s, subString(bin(s), offset), bin(bitSlice(s, offset));
select 5 as offset, 'Hello' as s, subString(bin(s), offset), bin(bitSlice(s, offset));
select 6 as offset, 'Hello' as s, subString(bin(s), offset), bin(bitSlice(s, offset));
select 7 as offset, 'Hello' as s, subString(bin(s), offset), bin(bitSlice(s, offset));
select 8 as offset, 'Hello' as s, subString(bin(s), offset), bin(bitSlice(s, offset));
select 9 as offset, 'Hello' as s, subString(bin(s), offset), bin(bitSlice(s, offset));
select 10 as offset, 'Hello' as s, subString(bin(s), offset), bin(bitSlice(s, offset));
select 11 as offset, 'Hello' as s, subString(bin(s), offset), bin(bitSlice(s, offset));
select 12 as offset, 'Hello' as s, subString(bin(s), offset), bin(bitSlice(s, offset));
select 13 as offset, 'Hello' as s, subString(bin(s), offset), bin(bitSlice(s, offset));
select 14 as offset, 'Hello' as s, subString(bin(s), offset), bin(bitSlice(s, offset));
select 15 as offset, 'Hello' as s, subString(bin(s), offset), bin(bitSlice(s, offset));
select 16 as offset, 'Hello' as s, subString(bin(s), offset), bin(bitSlice(s, offset));
select -1 as offset, 'Hello' as s, subString(bin(s), offset), bin(bitSlice(s, offset));
select -2 as offset, 'Hello' as s, subString(bin(s), offset), bin(bitSlice(s, offset));
select -3 as offset, 'Hello' as s, subString(bin(s), offset), bin(bitSlice(s, offset));
select -4 as offset, 'Hello' as s, subString(bin(s), offset), bin(bitSlice(s, offset));
select -5 as offset, 'Hello' as s, subString(bin(s), offset), bin(bitSlice(s, offset));
select -6 as offset, 'Hello' as s, subString(bin(s), offset), bin(bitSlice(s, offset));
select -7 as offset, 'Hello' as s, subString(bin(s), offset), bin(bitSlice(s, offset));
select -8 as offset, 'Hello' as s, subString(bin(s), offset), bin(bitSlice(s, offset));
select -9 as offset, 'Hello' as s, subString(bin(s), offset), bin(bitSlice(s, offset));
select -10 as offset, 'Hello' as s, subString(bin(s), offset), bin(bitSlice(s, offset));
select -11 as offset, 'Hello' as s, subString(bin(s), offset), bin(bitSlice(s, offset));
select -12 as offset, 'Hello' as s, subString(bin(s), offset), bin(bitSlice(s, offset));
select -13 as offset, 'Hello' as s, subString(bin(s), offset), bin(bitSlice(s, offset));
select -14 as offset, 'Hello' as s, subString(bin(s), offset), bin(bitSlice(s, offset));
select -15 as offset, 'Hello' as s, subString(bin(s), offset), bin(bitSlice(s, offset));
select -16 as offset, 'Hello' as s, subString(bin(s), offset), bin(bitSlice(s, offset));
SELECT 'Const Truncate Offset';
select 41 as offset, 'Hello' as s, subString(bin(s), offset), bin(bitSlice(s, offset));
select -41 as offset, 'Hello' as s, subString(bin(s), offset), bin(bitSlice(s, offset));
SELECT 'Const Nullable Offset';
select 1 as offset, null as s, subString(bin(s), offset), bin(bitSlice(s, offset));
select null as offset, 'Hello' as s, subString(bin(s), offset), bin(bitSlice(s, offset));
select null as offset, null as s, subString(bin(s), offset), bin(bitSlice(s, offset));
SELECT 'Const Offset, Const Length';
select 1 as offset, 1 as length, 'Hello' as s, subString(bin(s), offset, length), bin(bitSlice(s, offset, length));
select 2 as offset, 2 as length, 'Hello' as s, subString(bin(s), offset, length), bin(bitSlice(s, offset, length));
select 3 as offset, 3 as length, 'Hello' as s, subString(bin(s), offset, length), bin(bitSlice(s, offset, length));
select 4 as offset, 4 as length, 'Hello' as s, subString(bin(s), offset, length), bin(bitSlice(s, offset, length));
select 5 as offset, 5 as length, 'Hello' as s, subString(bin(s), offset, length), bin(bitSlice(s, offset, length));
select 6 as offset, 6 as length, 'Hello' as s, subString(bin(s), offset, length), bin(bitSlice(s, offset, length));
select 7 as offset, 7 as length, 'Hello' as s, subString(bin(s), offset, length), bin(bitSlice(s, offset, length));
select 8 as offset, 8 as length, 'Hello' as s, subString(bin(s), offset, length), bin(bitSlice(s, offset, length));
select 9 as offset, 9 as length, 'Hello' as s, subString(bin(s), offset, length), bin(bitSlice(s, offset, length));
select 10 as offset, 10 as length, 'Hello' as s, subString(bin(s), offset, length), bin(bitSlice(s, offset, length));
select 11 as offset, 11 as length, 'Hello' as s, subString(bin(s), offset, length), bin(bitSlice(s, offset, length));
select 12 as offset, 12 as length, 'Hello' as s, subString(bin(s), offset, length), bin(bitSlice(s, offset, length));
select 13 as offset, 13 as length, 'Hello' as s, subString(bin(s), offset, length), bin(bitSlice(s, offset, length));
select 14 as offset, 14 as length, 'Hello' as s, subString(bin(s), offset, length), bin(bitSlice(s, offset, length));
select 15 as offset, 15 as length, 'Hello' as s, subString(bin(s), offset, length), bin(bitSlice(s, offset, length));
select 16 as offset, 16 as length, 'Hello' as s, subString(bin(s), offset, length), bin(bitSlice(s, offset, length));
select 1 as offset, -1 as length, 'Hello' as s, subString(bin(s), offset, length), bin(bitSlice(s, offset, length));
select 2 as offset, -2 as length, 'Hello' as s, subString(bin(s), offset, length), bin(bitSlice(s, offset, length));
select 3 as offset, -3 as length, 'Hello' as s, subString(bin(s), offset, length), bin(bitSlice(s, offset, length));
select 4 as offset, -4 as length, 'Hello' as s, subString(bin(s), offset, length), bin(bitSlice(s, offset, length));
select 5 as offset, -5 as length, 'Hello' as s, subString(bin(s), offset, length), bin(bitSlice(s, offset, length));
select 6 as offset, -6 as length, 'Hello' as s, subString(bin(s), offset, length), bin(bitSlice(s, offset, length));
select 7 as offset, -7 as length, 'Hello' as s, subString(bin(s), offset, length), bin(bitSlice(s, offset, length));
select 8 as offset, -8 as length, 'Hello' as s, subString(bin(s), offset, length), bin(bitSlice(s, offset, length));
select 9 as offset, -9 as length, 'Hello' as s, subString(bin(s), offset, length), bin(bitSlice(s, offset, length));
select 10 as offset, -10 as length, 'Hello' as s, subString(bin(s), offset, length), bin(bitSlice(s, offset, length));
select 11 as offset, -11 as length, 'Hello' as s, subString(bin(s), offset, length), bin(bitSlice(s, offset, length));
select 12 as offset, -12 as length, 'Hello' as s, subString(bin(s), offset, length), bin(bitSlice(s, offset, length));
select 13 as offset, -13 as length, 'Hello' as s, subString(bin(s), offset, length), bin(bitSlice(s, offset, length));
select 14 as offset, -14 as length, 'Hello' as s, subString(bin(s), offset, length), bin(bitSlice(s, offset, length));
select 15 as offset, -15 as length, 'Hello' as s, subString(bin(s), offset, length), bin(bitSlice(s, offset, length));
select 16 as offset, -16 as length, 'Hello' as s, subString(bin(s), offset, length), bin(bitSlice(s, offset, length));
select -1 as offset, 1 as length, 'Hello' as s, subString(bin(s), offset, length), bin(bitSlice(s, offset, length));
select -2 as offset, 2 as length, 'Hello' as s, subString(bin(s), offset, length), bin(bitSlice(s, offset, length));
select -3 as offset, 3 as length, 'Hello' as s, subString(bin(s), offset, length), bin(bitSlice(s, offset, length));
select -4 as offset, 4 as length, 'Hello' as s, subString(bin(s), offset, length), bin(bitSlice(s, offset, length));
select -5 as offset, 5 as length, 'Hello' as s, subString(bin(s), offset, length), bin(bitSlice(s, offset, length));
select -6 as offset, 6 as length, 'Hello' as s, subString(bin(s), offset, length), bin(bitSlice(s, offset, length));
select -7 as offset, 7 as length, 'Hello' as s, subString(bin(s), offset, length), bin(bitSlice(s, offset, length));
select -8 as offset, 8 as length, 'Hello' as s, subString(bin(s), offset, length), bin(bitSlice(s, offset, length));
select -9 as offset, 9 as length, 'Hello' as s, subString(bin(s), offset, length), bin(bitSlice(s, offset, length));
select -10 as offset, 10 as length, 'Hello' as s, subString(bin(s), offset, length), bin(bitSlice(s, offset, length));
select -11 as offset, 11 as length, 'Hello' as s, subString(bin(s), offset, length), bin(bitSlice(s, offset, length));
select -12 as offset, 12 as length, 'Hello' as s, subString(bin(s), offset, length), bin(bitSlice(s, offset, length));
select -13 as offset, 13 as length, 'Hello' as s, subString(bin(s), offset, length), bin(bitSlice(s, offset, length));
select -14 as offset, 14 as length, 'Hello' as s, subString(bin(s), offset, length), bin(bitSlice(s, offset, length));
select -15 as offset, 15 as length, 'Hello' as s, subString(bin(s), offset, length), bin(bitSlice(s, offset, length));
select -16 as offset, 16 as length, 'Hello' as s, subString(bin(s), offset, length), bin(bitSlice(s, offset, length));
select -1 as offset, -16 as length, 'Hello' as s, subString(bin(s), offset, length), bin(bitSlice(s, offset, length));
select -2 as offset, -15 as length, 'Hello' as s, subString(bin(s), offset, length), bin(bitSlice(s, offset, length));
select -3 as offset, -14 as length, 'Hello' as s, subString(bin(s), offset, length), bin(bitSlice(s, offset, length));
select -4 as offset, -13 as length, 'Hello' as s, subString(bin(s), offset, length), bin(bitSlice(s, offset, length));
select -5 as offset, -12 as length, 'Hello' as s, subString(bin(s), offset, length), bin(bitSlice(s, offset, length));
select -6 as offset, -11 as length, 'Hello' as s, subString(bin(s), offset, length), bin(bitSlice(s, offset, length));
select -7 as offset, -10 as length, 'Hello' as s, subString(bin(s), offset, length), bin(bitSlice(s, offset, length));
select -8 as offset, -9 as length, 'Hello' as s, subString(bin(s), offset, length), bin(bitSlice(s, offset, length));
select -9 as offset, -8 as length, 'Hello' as s, subString(bin(s), offset, length), bin(bitSlice(s, offset, length));
select -10 as offset, -7 as length, 'Hello' as s, subString(bin(s), offset, length), bin(bitSlice(s, offset, length));
select -11 as offset, -6 as length, 'Hello' as s, subString(bin(s), offset, length), bin(bitSlice(s, offset, length));
select -12 as offset, -5 as length, 'Hello' as s, subString(bin(s), offset, length), bin(bitSlice(s, offset, length));
select -13 as offset, -4 as length, 'Hello' as s, subString(bin(s), offset, length), bin(bitSlice(s, offset, length));
select -14 as offset, -3 as length, 'Hello' as s, subString(bin(s), offset, length), bin(bitSlice(s, offset, length));
select -15 as offset, -2 as length, 'Hello' as s, subString(bin(s), offset, length), bin(bitSlice(s, offset, length));
select -16 as offset, -1 as length, 'Hello' as s, subString(bin(s), offset, length), bin(bitSlice(s, offset, length));
select 'Const Truncate Offset, Const Truncate Length';
select 36 as offset, 8 as length, 'Hello' as s, subString(bin(s), offset, length), bin(bitSlice(s, offset, length));
select 41 as offset, 1 as length, 'Hello' as s, subString(bin(s), offset, length), bin(bitSlice(s, offset, length));
select -44 as offset, -36 as length, 'Hello' as s, subString(bin(s), offset, length), bin(bitSlice(s, offset, length));
select -41 as offset, -40 as length, 'Hello' as s, subString(bin(s), offset, length), bin(bitSlice(s, offset, length));
select -41 as offset, 41 as length, 'Hello' as s, subString(bin(s), offset, length), bin(bitSlice(s, offset, length));
select 'Const Nullable Offset, Const Nullable Length';
select 1 as offset, 1 as length, null as s, subString(bin(s), offset , length), bin(bitSlice(s, offset, length));
select null as offset, 1 as length, 'Hello' as s, subString(bin(s), offset, length), bin(bitSlice(s, offset, length));
select 1 as offset, null as length, 'Hello' as s, subString(bin(s), offset , length), bin(bitSlice(s, offset, length));
select null as offset, null as length, null as s, subString(bin(s), offset , length), bin(bitSlice(s, offset, length));
select 'Dynamic Offset, Dynamic Length';
select number as offset, number as length, 'Hello' as s, subString(bin(s), offset , length), bin(bitSlice(s, offset, length)) from numbers(16);
select number as offset, -number as length, 'Hello' as s, subString(bin(s), offset , length), bin(bitSlice(s, offset, length)) from numbers(16);
select -number as offset, -16+number as length, 'Hello' as s, subString(bin(s), offset , length), bin(bitSlice(s, offset, length)) from numbers(16);
select -number as offset, number as length, 'Hello' as s, subString(bin(s), offset , length), bin(bitSlice(s, offset, length)) from numbers(16);
select 'Dynamic Truncate Offset, Dynamic Truncate Length';
select number-8 as offset, 8 as length, 'Hello' as s, subString(bin(s), offset , length), bin(bitSlice(s, offset, length)) from numbers(9);
select -4 as offset, number as length, 'Hello' as s, subString(bin(s), offset , length), bin(bitSlice(s, offset, length)) from numbers(9);
select -36-number as offset, 8 as length, 'Hello' as s, subString(bin(s), offset , length), bin(bitSlice(s, offset, length)) from numbers(9);
select -44 as offset, number as length, 'Hello' as s, subString(bin(s), offset , length), bin(bitSlice(s, offset, length)) from numbers(9);
select -44 as offset, number + 40 as length, 'Hello' as s, subString(bin(s), offset , length), bin(bitSlice(s, offset, length)) from numbers(9);
select 'Dynamic Nullable Offset, Dynamic Nullable Length';
select if(number%4 ==1 or number%8==7, null, number) as offset, if(number%4==2 or number%8==7, null, number) as length,if(number%4 ==3, null, 'Hello') as s,
subString(bin(s), offset, length), bin(bitSlice(s, offset , length))
from numbers(16);