support overlayUTF8

This commit is contained in:
taiyang-li 2024-07-24 14:17:58 +08:00
parent f4138ee6c6
commit fd3f0cf92b
5 changed files with 665 additions and 72 deletions

View File

@ -3,8 +3,10 @@
#include <DataTypes/DataTypeString.h>
#include <Functions/FunctionFactory.h>
#include <Functions/FunctionHelpers.h>
#include <Functions/GatherUtils/Sources.h>
#include <Functions/IFunction.h>
#include <Common/StringUtils.h>
#include <Common/UTF8Helpers.h>
namespace DB
{
@ -15,6 +17,8 @@ extern const int ILLEGAL_TYPE_OF_ARGUMENT;
extern const int NUMBER_OF_ARGUMENTS_DOESNT_MATCH;
}
using namespace GatherUtils;
namespace
{
@ -24,7 +28,7 @@ template <bool is_utf8>
class FunctionOverlay : public IFunction
{
public:
static constexpr auto name = is_utf8 ? "OverlayUTF8" : "Overlay";
static constexpr auto name = is_utf8 ? "overlayUTF8" : "overlay";
static FunctionPtr create(ContextPtr) { return std::make_shared<FunctionOverlay>(); }
String getName() const override { return name; }
@ -238,6 +242,15 @@ private:
}
}
/// get character count of a slice [data, data+bytes)
static size_t getSliceSize(const UInt8 * data, size_t bytes)
{
if constexpr (is_utf8)
return UTF8::countCodePoints(data, bytes);
else
return bytes;
}
template <bool three_args, bool offset_is_const, bool length_is_const>
void constantConstant(
size_t rows,
@ -257,13 +270,12 @@ private:
return;
}
size_t input_size = input.size;
size_t input_size = getSliceSize(reinterpret_cast<const UInt8 *>(input.data), input.size);
size_t valid_offset = 0; // start from 0, not negative
if constexpr (offset_is_const)
valid_offset = getValidOffset(const_offset, input_size);
size_t replace_size = replace.size;
Int64 length = 0; // maybe negative
size_t replace_size = getSliceSize(reinterpret_cast<const UInt8 *>(replace.data), replace.size);
size_t valid_length = 0; // not negative
if constexpr (!three_args && length_is_const)
{
@ -276,6 +288,9 @@ private:
}
Int64 offset = 0; // start from 1, maybe negative
Int64 length = 0; // maybe negative
const UInt8 * input_begin = reinterpret_cast<const UInt8 *>(input.data);
const UInt8 * input_end = reinterpret_cast<const UInt8 *>(input.data + input.size);
size_t res_offset = 0;
for (size_t i = 0; i < rows; ++i)
{
@ -293,28 +308,57 @@ private:
size_t prefix_size = valid_offset;
size_t suffix_size = prefix_size + valid_length > input_size ? 0 : input_size - prefix_size - valid_length;
size_t new_res_size = res_data.size() + prefix_size + replace_size + suffix_size + 1; /// +1 for zero terminator
res_data.resize(new_res_size);
/// copy prefix before replaced region
memcpySmallAllowReadWriteOverflow15(&res_data[res_offset], input.data, prefix_size);
res_offset += prefix_size;
/// copy replace
memcpySmallAllowReadWriteOverflow15(&res_data[res_offset], replace.data, replace_size);
res_offset += replace_size;
/// copy suffix after replaced region. It is not necessary to copy if suffix_size is zero.
if (suffix_size)
if constexpr (!is_utf8)
{
memcpySmallAllowReadWriteOverflow15(&res_data[res_offset], input.data + prefix_size + valid_length, suffix_size);
res_offset += suffix_size;
size_t new_res_size = res_data.size() + prefix_size + replace_size + suffix_size + 1; /// +1 for zero terminator
res_data.resize(new_res_size);
/// copy prefix before replaced region
memcpySmallAllowReadWriteOverflow15(&res_data[res_offset], input.data, prefix_size);
res_offset += prefix_size;
/// copy replace
memcpySmallAllowReadWriteOverflow15(&res_data[res_offset], replace.data, replace_size);
res_offset += replace_size;
/// copy suffix after replaced region. It is not necessary to copy if suffix_size is zero.
if (suffix_size)
{
memcpySmallAllowReadWriteOverflow15(&res_data[res_offset], input.data + prefix_size + valid_length, suffix_size);
res_offset += suffix_size;
}
}
else
{
const auto * prefix_end = UTF8StringSource::skipCodePointsForward(input_begin, prefix_size, input_end);
size_t prefix_bytes = prefix_end > input_end ? input.size : prefix_end - input_begin;
const auto * suffix_begin = UTF8StringSource::skipCodePointsBackward(input_end, suffix_size, input_begin);
size_t suffix_bytes = input_end - suffix_begin;
size_t new_res_size = res_data.size() + prefix_bytes + replace.size + suffix_bytes + 1; /// +1 for zero terminator
res_data.resize(new_res_size);
/// copy prefix before replaced region
memcpySmallAllowReadWriteOverflow15(&res_data[res_offset], input_begin, prefix_bytes);
res_offset += prefix_bytes;
/// copy replace
memcpySmallAllowReadWriteOverflow15(&res_data[res_offset], replace.data, replace.size);
res_offset += replace.size;
/// copy suffix after replaced region. It is not necessary to copy if suffix_bytes is zero.
if (suffix_bytes)
{
memcpySmallAllowReadWriteOverflow15(&res_data[res_offset], suffix_begin, suffix_bytes);
res_offset += suffix_bytes;
}
}
/// add zero terminator
res_data[res_offset] = 0;
++res_offset;
res_offsets[i] = res_offset;
}
}
@ -338,7 +382,7 @@ private:
return;
}
size_t replace_size = replace.size;
size_t replace_size = getSliceSize(reinterpret_cast<const UInt8 *>(replace.data), replace.size);
Int64 length = 0; // maybe negative
size_t valid_length = 0; // not negative
if constexpr (!three_args && length_is_const)
@ -358,7 +402,8 @@ private:
for (size_t i = 0; i < rows; ++i)
{
size_t input_offset = input_offsets[i - 1];
size_t input_size = input_offsets[i] - input_offsets[i - 1] - 1;
size_t input_bytes = input_offsets[i] - input_offsets[i - 1] - 1;
size_t input_size = getSliceSize(&input_data[input_offset], input_bytes);
if constexpr (offset_is_const)
{
@ -378,29 +423,59 @@ private:
size_t prefix_size = valid_offset;
size_t suffix_size = prefix_size + valid_length > input_size ? 0 : input_size - prefix_size - valid_length;
size_t new_res_size = res_data.size() + prefix_size + replace_size + suffix_size + 1; /// +1 for zero terminator
res_data.resize(new_res_size);
/// copy prefix before replaced region
memcpySmallAllowReadWriteOverflow15(&res_data[res_offset], &input_data[input_offset], prefix_size);
res_offset += prefix_size;
/// copy replace
memcpySmallAllowReadWriteOverflow15(&res_data[res_offset], replace.data, replace_size);
res_offset += replace_size;
/// copy suffix after replaced region. It is not necessary to copy if suffix_size is zero.
if (suffix_size)
if constexpr (!is_utf8)
{
memcpySmallAllowReadWriteOverflow15(
&res_data[res_offset], &input_data[input_offset + prefix_size + valid_length], suffix_size);
res_offset += suffix_size;
size_t new_res_size = res_data.size() + prefix_size + replace_size + suffix_size + 1; /// +1 for zero terminator
res_data.resize(new_res_size);
/// copy prefix before replaced region
memcpySmallAllowReadWriteOverflow15(&res_data[res_offset], &input_data[input_offset], prefix_size);
res_offset += prefix_size;
/// copy replace
memcpySmallAllowReadWriteOverflow15(&res_data[res_offset], replace.data, replace_size);
res_offset += replace_size;
/// copy suffix after replaced region. It is not necessary to copy if suffix_size is zero.
if (suffix_size)
{
memcpySmallAllowReadWriteOverflow15(
&res_data[res_offset], &input_data[input_offset + prefix_size + valid_length], suffix_size);
res_offset += suffix_size;
}
}
else
{
const auto * input_begin = &input_data[input_offset];
const auto * input_end = &input_data[input_offset + input_bytes];
const auto * prefix_end = UTF8StringSource::skipCodePointsForward(input_begin, prefix_size, input_end);
size_t prefix_bytes = prefix_end > input_end ? input_bytes : prefix_end - input_begin;
const auto * suffix_begin = UTF8StringSource::skipCodePointsBackward(input_end, suffix_size, input_begin);
size_t suffix_bytes = input_end - suffix_begin;
size_t new_res_size = res_data.size() + prefix_bytes + replace.size + suffix_bytes + 1; /// +1 for zero terminator
res_data.resize(new_res_size);
/// copy prefix before replaced region
memcpySmallAllowReadWriteOverflow15(&res_data[res_offset], &input_data[input_offset], prefix_bytes);
res_offset += prefix_bytes;
/// copy replace
memcpySmallAllowReadWriteOverflow15(&res_data[res_offset], replace.data, replace.size);
res_offset += replace.size;
/// copy suffix after replaced region. It is not necessary to copy if suffix_bytes is zero.
if (suffix_bytes)
{
memcpySmallAllowReadWriteOverflow15(&res_data[res_offset], suffix_begin, suffix_bytes);
res_offset += suffix_bytes;
}
}
/// add zero terminator
res_data[res_offset] = 0;
++res_offset;
res_offsets[i] = res_offset;
}
}
@ -424,7 +499,7 @@ private:
return;
}
size_t input_size = input.size;
size_t input_size = getSliceSize(reinterpret_cast<const UInt8 *>(input.data), input.size);
size_t valid_offset = 0; // start from 0, not negative
if constexpr (offset_is_const)
valid_offset = getValidOffset(const_offset, input_size);
@ -438,12 +513,15 @@ private:
}
size_t rows = replace_offsets.size();
const auto * input_begin = reinterpret_cast<const UInt8 *>(input.data);
const auto * input_end = reinterpret_cast<const UInt8 *>(input.data + input.size);
Int64 offset = 0; // start from 1, maybe negative
size_t res_offset = 0;
for (size_t i = 0; i < rows; ++i)
{
size_t replace_offset = replace_offsets[i - 1];
size_t replace_size = replace_offsets[i] - replace_offsets[i - 1] - 1;
size_t replace_bytes = replace_offsets[i] - replace_offsets[i - 1] - 1;
size_t replace_size = getSliceSize(&replace_data[replace_offset], replace_bytes);
if constexpr (!offset_is_const)
{
@ -463,28 +541,55 @@ private:
size_t prefix_size = valid_offset;
size_t suffix_size = prefix_size + valid_length > input_size ? 0 : input_size - prefix_size - valid_length;
size_t new_res_size = res_data.size() + prefix_size + replace_size + suffix_size + 1; /// +1 for zero terminator
res_data.resize(new_res_size);
/// copy prefix before replaced region
memcpySmallAllowReadWriteOverflow15(&res_data[res_offset], input.data, prefix_size);
res_offset += prefix_size;
/// copy replace
memcpySmallAllowReadWriteOverflow15(&res_data[res_offset], &replace_data[replace_offset], replace_size);
res_offset += replace_size;
/// copy suffix after replaced region. It is not necessary to copy if suffix_size is zero.
if (suffix_size)
if constexpr (!is_utf8)
{
memcpySmallAllowReadWriteOverflow15(&res_data[res_offset], input.data + prefix_size + valid_length, suffix_size);
res_offset += suffix_size;
size_t new_res_size = res_data.size() + prefix_size + replace_size + suffix_size + 1; /// +1 for zero terminator
res_data.resize(new_res_size);
/// copy prefix before replaced region
memcpySmallAllowReadWriteOverflow15(&res_data[res_offset], input.data, prefix_size);
res_offset += prefix_size;
/// copy replace
memcpySmallAllowReadWriteOverflow15(&res_data[res_offset], &replace_data[replace_offset], replace_size);
res_offset += replace_size;
/// copy suffix after replaced region. It is not necessary to copy if suffix_size is zero.
if (suffix_size)
{
memcpySmallAllowReadWriteOverflow15(&res_data[res_offset], input.data + prefix_size + valid_length, suffix_size);
res_offset += suffix_size;
}
}
else
{
const auto * prefix_end = UTF8StringSource::skipCodePointsForward(input_begin, prefix_size, input_end);
size_t prefix_bytes = prefix_end > input_end ? input.size : prefix_end - input_begin;
const auto * suffix_begin = UTF8StringSource::skipCodePointsBackward(input_end, suffix_size, input_begin);
size_t suffix_bytes = input_end - suffix_begin;
size_t new_res_size = res_data.size() + prefix_bytes + replace_bytes + suffix_bytes + 1; /// +1 for zero terminator
res_data.resize(new_res_size);
/// copy prefix before replaced region
memcpySmallAllowReadWriteOverflow15(&res_data[res_offset], input_begin, prefix_bytes);
res_offset += prefix_bytes;
/// copy replace
memcpySmallAllowReadWriteOverflow15(&res_data[res_offset], &replace_data[replace_offset], replace_bytes);
res_offset += replace_bytes;
/// copy suffix after replaced region. It is not necessary to copy if suffix_bytes is zero
if (suffix_bytes)
{
memcpySmallAllowReadWriteOverflow15(&res_data[res_offset], suffix_begin, suffix_bytes);
res_offset += suffix_bytes;
}
}
/// add zero terminator
res_data[res_offset] = 0;
++res_offset;
res_offsets[i] = res_offset;
}
}
@ -533,9 +638,12 @@ private:
for (size_t i = 0; i < rows; ++i)
{
size_t input_offset = input_offsets[i - 1];
size_t input_size = input_offsets[i] - input_offsets[i - 1] - 1;
size_t input_bytes = input_offsets[i] - input_offsets[i - 1] - 1;
size_t input_size = getSliceSize(&input_data[input_offset], input_bytes);
size_t replace_offset = replace_offsets[i - 1];
size_t replace_size = replace_offsets[i] - replace_offsets[i - 1] - 1;
size_t replace_bytes = replace_offsets[i] - replace_offsets[i - 1] - 1;
size_t replace_size = getSliceSize(&replace_data[replace_offset], replace_bytes);
if constexpr (offset_is_const)
{
@ -559,29 +667,58 @@ private:
size_t prefix_size = valid_offset;
size_t suffix_size = prefix_size + valid_length > input_size ? 0 : input_size - prefix_size - valid_length;
size_t new_res_size = res_data.size() + prefix_size + replace_size + suffix_size + 1; /// +1 for zero terminator
res_data.resize(new_res_size);
/// copy prefix before replaced region
memcpySmallAllowReadWriteOverflow15(&res_data[res_offset], &input_data[input_offset], prefix_size);
res_offset += prefix_size;
/// copy replace
memcpySmallAllowReadWriteOverflow15(&res_data[res_offset], &replace_data[replace_offset], replace_size);
res_offset += replace_size;
/// copy suffix after replaced region. It is not necessary to copy if suffix_size is zero.
if (suffix_size)
if constexpr (!is_utf8)
{
memcpySmallAllowReadWriteOverflow15(
&res_data[res_offset], &input_data[input_offset + prefix_size + valid_length], suffix_size);
res_offset += suffix_size;
size_t new_res_size = res_data.size() + prefix_size + replace_size + suffix_size + 1; /// +1 for zero terminator
res_data.resize(new_res_size);
/// copy prefix before replaced region
memcpySmallAllowReadWriteOverflow15(&res_data[res_offset], &input_data[input_offset], prefix_size);
res_offset += prefix_size;
/// copy replace
memcpySmallAllowReadWriteOverflow15(&res_data[res_offset], &replace_data[replace_offset], replace_size);
res_offset += replace_size;
/// copy suffix after replaced region. It is not necessary to copy if suffix_size is zero.
if (suffix_size)
{
memcpySmallAllowReadWriteOverflow15(
&res_data[res_offset], &input_data[input_offset + prefix_size + valid_length], suffix_size);
res_offset += suffix_size;
}
}
else
{
const auto * input_begin = &input_data[input_offset];
const auto * input_end = &input_data[input_offset + input_bytes];
const auto * prefix_end = UTF8StringSource::skipCodePointsForward(input_begin, prefix_size, input_end);
size_t prefix_bytes = prefix_end > input_end ? input_bytes : prefix_end - input_begin;
const auto * suffix_begin = UTF8StringSource::skipCodePointsBackward(input_end, suffix_size, input_begin);
size_t suffix_bytes = input_end - suffix_begin;
size_t new_res_size = res_data.size() + prefix_bytes + replace_bytes + suffix_bytes + 1; /// +1 for zero terminator
res_data.resize(new_res_size);
/// copy prefix before replaced region
memcpySmallAllowReadWriteOverflow15(&res_data[res_offset], input_begin, prefix_bytes);
res_offset += prefix_bytes;
/// copy replace
memcpySmallAllowReadWriteOverflow15(&res_data[res_offset], &replace_data[replace_offset], replace_bytes);
res_offset += replace_bytes;
/// copy suffix after replaced region. It is not necessary to copy if suffix_bytes is zero.
if (suffix_bytes)
{
memcpySmallAllowReadWriteOverflow15(&res_data[res_offset], suffix_begin, suffix_bytes);
res_offset += suffix_bytes;
}
}
/// add zero terminator
res_data[res_offset] = 0;
++res_offset;
res_offsets[i] = res_offset;
}
}

View File

@ -0,0 +1,168 @@
Spark ANSI SQL
Spark ANSI SQL
Spark ANSI SQL
Spark ANSI SQL
Spark ANSI SQL
Spark ANSI SQL
Spark ANSI SQL
Spark ANSI SQL
Spark ANSI SQL
Spark ANSI SQL
Spark ANSI SQL
Spark ANSI SQL
Spark ANSI SQL
Spark ANSI SQL
Spark ANSI SQL
Spark ANSI SQL
Spark ANSI SQL
Spark ANSI SQL
Spark ANSI SQL
Spark ANSI SQL
Spark ANSI SQL
Spark ANSI SQL
Spark ANSI SQL
Spark ANSI SQL
Spark ANSI SQL
Spark ANSI SQL
Spark ANSI SQL
Spark ANSI SQL
Spark ANSI SQL
Spark ANSI SQL
Spark ANSI SQL
Spark ANSI SQL
Spark ANSI SQL
Spark ANSI SQL
Spark ANSI SQL
Spark ANSI SQL
Spark ANSI SQL
Spark ANSI SQL
Spark ANSI SQL
Spark ANSI SQL
Spark ANSI SQL
Spark ANSI SQL
Spark ANSI SQL
Spark ANSI SQL
Spark ANSI SQL
Spark ANSI SQL
Spark ANSI SQL
Spark ANSI SQL
Spark_SQL
Spark_SQL
Spark_SQL
Spark_SQL
Spark_SQL
Spark_SQL
Spark_SQL
Spark_SQL
Spark_SQL
Spark_SQL
Spark_SQL
Spark_SQL
Spark_SQL
Spark_SQL
Spark_SQL
Spark_SQL
Spark_SQL
Spark_SQL
Spark_SQL
Spark_SQL
Spark_SQL
Spark_SQL
Spark_SQL
Spark_SQL
Spark CORE
Spark CORE
Spark CORE
Spark CORE
Spark CORE
Spark CORE
Spark CORE
Spark CORE
Spark CORE
Spark CORE
Spark CORE
Spark CORE
Spark CORE
Spark CORE
Spark CORE
Spark CORE
Spark CORE
Spark CORE
Spark CORE
Spark CORE
Spark CORE
Spark CORE
Spark CORE
Spark CORE
Spark ANSI SQL
Spark ANSI SQL
Spark ANSI SQL
Spark ANSI SQL
Spark ANSI SQL
Spark ANSI SQL
Spark ANSI SQL
Spark ANSI SQL
Spark ANSI SQL
Spark ANSI SQL
Spark ANSI SQL
Spark ANSI SQL
Spark ANSI SQL
Spark ANSI SQL
Spark ANSI SQL
Spark ANSI SQL
Spark ANSI SQL
Spark ANSI SQL
Spark ANSI SQL
Spark ANSI SQL
Spark ANSI SQL
Spark ANSI SQL
Spark ANSI SQL
Spark ANSI SQL
Spark ANSI SQL
Spark ANSI SQL
Spark ANSI SQL
Spark ANSI SQL
Spark ANSI SQL
Spark ANSI SQL
Spark ANSI SQL
Spark ANSI SQL
Spark ANSI SQL
Spark ANSI SQL
Spark ANSI SQL
Spark ANSI SQL
Structured SQL
Structured SQL
Structured SQL
Structured SQL
Structured SQL
Structured SQL
Structured SQL
Structured SQL
Structured SQL
Structured SQL
Structured SQL
Structured SQL
Structured SQL
Structured SQL
Structured SQL
Structured SQL
Structured SQL
Structured SQL
Structured SQL
Structured SQL
Structured SQL
Structured SQL
Structured SQL
Structured SQL
Structured SQL
Structured SQL
Structured SQL
Structured SQL
Structured SQL
Structured SQL
Structured SQL
Structured SQL
Structured SQL
Structured SQL
Structured SQL
Structured SQL

View File

@ -0,0 +1,60 @@
SELECT overlay('Spark SQL', 'ANSI ', 7, 0) from numbers(3);
SELECT overlay(materialize('Spark SQL'), 'ANSI ', 7, 0) from numbers(3);
SELECT overlay('Spark SQL', materialize('ANSI '), 7, 0) from numbers(3);
SELECT overlay('Spark SQL', 'ANSI ', materialize(7), 0) from numbers(3);
SELECT overlay('Spark SQL', 'ANSI ', 7, materialize(0)) from numbers(3);
SELECT overlay(materialize('Spark SQL'), materialize('ANSI '), 7, 0) from numbers(3);
SELECT overlay(materialize('Spark SQL'), 'ANSI ', materialize(7), 0) from numbers(3);
SELECT overlay(materialize('Spark SQL'), 'ANSI ', 7, materialize(0)) from numbers(3);
SELECT overlay('Spark SQL', materialize('ANSI '), materialize(7), 0) from numbers(3);
SELECT overlay('Spark SQL', materialize('ANSI '), 7, materialize(0)) from numbers(3);
SELECT overlay('Spark SQL', 'ANSI ', materialize(7), materialize(0)) from numbers(3);
SELECT overlay(materialize('Spark SQL'), materialize('ANSI '), materialize(7), 0) from numbers(3);
SELECT overlay(materialize('Spark SQL'), materialize('ANSI '), 7, materialize(0)) from numbers(3);
SELECT overlay(materialize('Spark SQL'), 'ANSI ', materialize(7), materialize(0)) from numbers(3);
SELECT overlay('Spark SQL', materialize('ANSI '), materialize(7), materialize(0)) from numbers(3);
SELECT overlay(materialize('Spark SQL'), materialize('ANSI '), materialize(7), materialize(0)) from numbers(3);
SELECT overlay('Spark SQL', '_', 6) from numbers(3);
SELECT overlay(materialize('Spark SQL'), '_', 6) from numbers(3);
SELECT overlay('Spark SQL', materialize('_'), 6) from numbers(3);
SELECT overlay('Spark SQL', '_', materialize(6)) from numbers(3);
SELECT overlay(materialize('Spark SQL'), materialize('_'), 6) from numbers(3);
SELECT overlay(materialize('Spark SQL'), '_', materialize(6)) from numbers(3);
SELECT overlay('Spark SQL', materialize('_'), materialize(6)) from numbers(3);
SELECT overlay(materialize('Spark SQL'), materialize('_'), materialize(6)) from numbers(3);
SELECT overlay('Spark SQL', 'CORE', 7) from numbers(3);
SELECT overlay(materialize('Spark SQL'), 'CORE', 7) from numbers(3);
SELECT overlay('Spark SQL', materialize('CORE'), 7) from numbers(3);
SELECT overlay('Spark SQL', 'CORE', materialize(7)) from numbers(3);
SELECT overlay(materialize('Spark SQL'), materialize('CORE'), 7) from numbers(3);
SELECT overlay(materialize('Spark SQL'), 'CORE', materialize(7)) from numbers(3);
SELECT overlay('Spark SQL', materialize('CORE'), materialize(7)) from numbers(3);
SELECT overlay(materialize('Spark SQL'), materialize('CORE'), materialize(7)) from numbers(3);
SELECT overlay('Spark SQL', 'ANSI ', 7, 0) from numbers(3);
SELECT overlay(materialize('Spark SQL'), 'ANSI ', 7, 0) from numbers(3);
SELECT overlay('Spark SQL', materialize('ANSI '), 7, 0) from numbers(3);
SELECT overlay('Spark SQL', 'ANSI ', materialize(7), 0) from numbers(3);
SELECT overlay('Spark SQL', 'ANSI ', 7, materialize(0)) from numbers(3);
SELECT overlay(materialize('Spark SQL'), materialize('ANSI '), 7, 0) from numbers(3);
SELECT overlay(materialize('Spark SQL'), 'ANSI ', materialize(7), 0) from numbers(3);
SELECT overlay(materialize('Spark SQL'), 'ANSI ', 7, materialize(0)) from numbers(3);
SELECT overlay('Spark SQL', materialize('ANSI '), materialize(7), 0) from numbers(3);
SELECT overlay('Spark SQL', materialize('ANSI '), 7, materialize(0)) from numbers(3);
SELECT overlay('Spark SQL', 'ANSI ', materialize(7), materialize(0)) from numbers(3);
SELECT overlay(materialize('Spark SQL'), materialize('ANSI '), materialize(7), materialize(0)) from numbers(3);
SELECT overlay('Spark SQL', 'tructured', 2, 4) from numbers(3);
SELECT overlay(materialize('Spark SQL'), 'tructured', 2, 4) from numbers(3);
SELECT overlay('Spark SQL', materialize('tructured'), 2, 4) from numbers(3);
SELECT overlay('Spark SQL', 'tructured', materialize(2), 4) from numbers(3);
SELECT overlay('Spark SQL', 'tructured', 2, materialize(4)) from numbers(3);
SELECT overlay(materialize('Spark SQL'), materialize('tructured'), 2, 4) from numbers(3);
SELECT overlay(materialize('Spark SQL'), 'tructured', materialize(2), 4) from numbers(3);
SELECT overlay(materialize('Spark SQL'), 'tructured', 2, materialize(4)) from numbers(3);
SELECT overlay('Spark SQL', materialize('tructured'), materialize(2), 4) from numbers(3);
SELECT overlay('Spark SQL', materialize('tructured'), 2, materialize(4)) from numbers(3);
SELECT overlay('Spark SQL', 'tructured', materialize(2), materialize(4)) from numbers(3);
SELECT overlay(materialize('Spark SQL'), materialize('tructured'), materialize(2), materialize(4)) from numbers(3);

View File

@ -0,0 +1,168 @@
Spark ANSI SQL和CH
Spark ANSI SQL和CH
Spark ANSI SQL和CH
Spark ANSI SQL和CH
Spark ANSI SQL和CH
Spark ANSI SQL和CH
Spark ANSI SQL和CH
Spark ANSI SQL和CH
Spark ANSI SQL和CH
Spark ANSI SQL和CH
Spark ANSI SQL和CH
Spark ANSI SQL和CH
Spark ANSI SQL和CH
Spark ANSI SQL和CH
Spark ANSI SQL和CH
Spark ANSI SQL和CH
Spark ANSI SQL和CH
Spark ANSI SQL和CH
Spark ANSI SQL和CH
Spark ANSI SQL和CH
Spark ANSI SQL和CH
Spark ANSI SQL和CH
Spark ANSI SQL和CH
Spark ANSI SQL和CH
Spark ANSI SQL和CH
Spark ANSI SQL和CH
Spark ANSI SQL和CH
Spark ANSI SQL和CH
Spark ANSI SQL和CH
Spark ANSI SQL和CH
Spark ANSI SQL和CH
Spark ANSI SQL和CH
Spark ANSI SQL和CH
Spark ANSI SQL和CH
Spark ANSI SQL和CH
Spark ANSI SQL和CH
Spark ANSI SQL和CH
Spark ANSI SQL和CH
Spark ANSI SQL和CH
Spark ANSI SQL和CH
Spark ANSI SQL和CH
Spark ANSI SQL和CH
Spark ANSI SQL和CH
Spark ANSI SQL和CH
Spark ANSI SQL和CH
Spark ANSI SQL和CH
Spark ANSI SQL和CH
Spark ANSI SQL和CH
Spark_SQL和CH
Spark_SQL和CH
Spark_SQL和CH
Spark_SQL和CH
Spark_SQL和CH
Spark_SQL和CH
Spark_SQL和CH
Spark_SQL和CH
Spark_SQL和CH
Spark_SQL和CH
Spark_SQL和CH
Spark_SQL和CH
Spark_SQL和CH
Spark_SQL和CH
Spark_SQL和CH
Spark_SQL和CH
Spark_SQL和CH
Spark_SQL和CH
Spark_SQL和CH
Spark_SQL和CH
Spark_SQL和CH
Spark_SQL和CH
Spark_SQL和CH
Spark_SQL和CH
Spark CORECH
Spark CORECH
Spark CORECH
Spark CORECH
Spark CORECH
Spark CORECH
Spark CORECH
Spark CORECH
Spark CORECH
Spark CORECH
Spark CORECH
Spark CORECH
Spark CORECH
Spark CORECH
Spark CORECH
Spark CORECH
Spark CORECH
Spark CORECH
Spark CORECH
Spark CORECH
Spark CORECH
Spark CORECH
Spark CORECH
Spark CORECH
Spark ANSI SQL和CH
Spark ANSI SQL和CH
Spark ANSI SQL和CH
Spark ANSI SQL和CH
Spark ANSI SQL和CH
Spark ANSI SQL和CH
Spark ANSI SQL和CH
Spark ANSI SQL和CH
Spark ANSI SQL和CH
Spark ANSI SQL和CH
Spark ANSI SQL和CH
Spark ANSI SQL和CH
Spark ANSI SQL和CH
Spark ANSI SQL和CH
Spark ANSI SQL和CH
Spark ANSI SQL和CH
Spark ANSI SQL和CH
Spark ANSI SQL和CH
Spark ANSI SQL和CH
Spark ANSI SQL和CH
Spark ANSI SQL和CH
Spark ANSI SQL和CH
Spark ANSI SQL和CH
Spark ANSI SQL和CH
Spark ANSI SQL和CH
Spark ANSI SQL和CH
Spark ANSI SQL和CH
Spark ANSI SQL和CH
Spark ANSI SQL和CH
Spark ANSI SQL和CH
Spark ANSI SQL和CH
Spark ANSI SQL和CH
Spark ANSI SQL和CH
Spark ANSI SQL和CH
Spark ANSI SQL和CH
Spark ANSI SQL和CH
Structured SQL和CH
Structured SQL和CH
Structured SQL和CH
Structured SQL和CH
Structured SQL和CH
Structured SQL和CH
Structured SQL和CH
Structured SQL和CH
Structured SQL和CH
Structured SQL和CH
Structured SQL和CH
Structured SQL和CH
Structured SQL和CH
Structured SQL和CH
Structured SQL和CH
Structured SQL和CH
Structured SQL和CH
Structured SQL和CH
Structured SQL和CH
Structured SQL和CH
Structured SQL和CH
Structured SQL和CH
Structured SQL和CH
Structured SQL和CH
Structured SQL和CH
Structured SQL和CH
Structured SQL和CH
Structured SQL和CH
Structured SQL和CH
Structured SQL和CH
Structured SQL和CH
Structured SQL和CH
Structured SQL和CH
Structured SQL和CH
Structured SQL和CH
Structured SQL和CH

View File

@ -0,0 +1,60 @@
SELECT overlayUTF8('Spark SQL和CH', 'ANSI ', 7, 0) from numbers(3);
SELECT overlayUTF8(materialize('Spark SQL和CH'), 'ANSI ', 7, 0) from numbers(3);
SELECT overlayUTF8('Spark SQL和CH', materialize('ANSI '), 7, 0) from numbers(3);
SELECT overlayUTF8('Spark SQL和CH', 'ANSI ', materialize(7), 0) from numbers(3);
SELECT overlayUTF8('Spark SQL和CH', 'ANSI ', 7, materialize(0)) from numbers(3);
SELECT overlayUTF8(materialize('Spark SQL和CH'), materialize('ANSI '), 7, 0) from numbers(3);
SELECT overlayUTF8(materialize('Spark SQL和CH'), 'ANSI ', materialize(7), 0) from numbers(3);
SELECT overlayUTF8(materialize('Spark SQL和CH'), 'ANSI ', 7, materialize(0)) from numbers(3);
SELECT overlayUTF8('Spark SQL和CH', materialize('ANSI '), materialize(7), 0) from numbers(3);
SELECT overlayUTF8('Spark SQL和CH', materialize('ANSI '), 7, materialize(0)) from numbers(3);
SELECT overlayUTF8('Spark SQL和CH', 'ANSI ', materialize(7), materialize(0)) from numbers(3);
SELECT overlayUTF8(materialize('Spark SQL和CH'), materialize('ANSI '), materialize(7), 0) from numbers(3);
SELECT overlayUTF8(materialize('Spark SQL和CH'), materialize('ANSI '), 7, materialize(0)) from numbers(3);
SELECT overlayUTF8(materialize('Spark SQL和CH'), 'ANSI ', materialize(7), materialize(0)) from numbers(3);
SELECT overlayUTF8('Spark SQL和CH', materialize('ANSI '), materialize(7), materialize(0)) from numbers(3);
SELECT overlayUTF8(materialize('Spark SQL和CH'), materialize('ANSI '), materialize(7), materialize(0)) from numbers(3);
SELECT overlayUTF8('Spark SQL和CH', '_', 6) from numbers(3);
SELECT overlayUTF8(materialize('Spark SQL和CH'), '_', 6) from numbers(3);
SELECT overlayUTF8('Spark SQL和CH', materialize('_'), 6) from numbers(3);
SELECT overlayUTF8('Spark SQL和CH', '_', materialize(6)) from numbers(3);
SELECT overlayUTF8(materialize('Spark SQL和CH'), materialize('_'), 6) from numbers(3);
SELECT overlayUTF8(materialize('Spark SQL和CH'), '_', materialize(6)) from numbers(3);
SELECT overlayUTF8('Spark SQL和CH', materialize('_'), materialize(6)) from numbers(3);
SELECT overlayUTF8(materialize('Spark SQL和CH'), materialize('_'), materialize(6)) from numbers(3);
SELECT overlayUTF8('Spark SQL和CH', 'CORE', 7) from numbers(3);
SELECT overlayUTF8(materialize('Spark SQL和CH'), 'CORE', 7) from numbers(3);
SELECT overlayUTF8('Spark SQL和CH', materialize('CORE'), 7) from numbers(3);
SELECT overlayUTF8('Spark SQL和CH', 'CORE', materialize(7)) from numbers(3);
SELECT overlayUTF8(materialize('Spark SQL和CH'), materialize('CORE'), 7) from numbers(3);
SELECT overlayUTF8(materialize('Spark SQL和CH'), 'CORE', materialize(7)) from numbers(3);
SELECT overlayUTF8('Spark SQL和CH', materialize('CORE'), materialize(7)) from numbers(3);
SELECT overlayUTF8(materialize('Spark SQL和CH'), materialize('CORE'), materialize(7)) from numbers(3);
SELECT overlayUTF8('Spark SQL和CH', 'ANSI ', 7, 0) from numbers(3);
SELECT overlayUTF8(materialize('Spark SQL和CH'), 'ANSI ', 7, 0) from numbers(3);
SELECT overlayUTF8('Spark SQL和CH', materialize('ANSI '), 7, 0) from numbers(3);
SELECT overlayUTF8('Spark SQL和CH', 'ANSI ', materialize(7), 0) from numbers(3);
SELECT overlayUTF8('Spark SQL和CH', 'ANSI ', 7, materialize(0)) from numbers(3);
SELECT overlayUTF8(materialize('Spark SQL和CH'), materialize('ANSI '), 7, 0) from numbers(3);
SELECT overlayUTF8(materialize('Spark SQL和CH'), 'ANSI ', materialize(7), 0) from numbers(3);
SELECT overlayUTF8(materialize('Spark SQL和CH'), 'ANSI ', 7, materialize(0)) from numbers(3);
SELECT overlayUTF8('Spark SQL和CH', materialize('ANSI '), materialize(7), 0) from numbers(3);
SELECT overlayUTF8('Spark SQL和CH', materialize('ANSI '), 7, materialize(0)) from numbers(3);
SELECT overlayUTF8('Spark SQL和CH', 'ANSI ', materialize(7), materialize(0)) from numbers(3);
SELECT overlayUTF8(materialize('Spark SQL和CH'), materialize('ANSI '), materialize(7), materialize(0)) from numbers(3);
SELECT overlayUTF8('Spark SQL和CH', 'tructured', 2, 4) from numbers(3);
SELECT overlayUTF8(materialize('Spark SQL和CH'), 'tructured', 2, 4) from numbers(3);
SELECT overlayUTF8('Spark SQL和CH', materialize('tructured'), 2, 4) from numbers(3);
SELECT overlayUTF8('Spark SQL和CH', 'tructured', materialize(2), 4) from numbers(3);
SELECT overlayUTF8('Spark SQL和CH', 'tructured', 2, materialize(4)) from numbers(3);
SELECT overlayUTF8(materialize('Spark SQL和CH'), materialize('tructured'), 2, 4) from numbers(3);
SELECT overlayUTF8(materialize('Spark SQL和CH'), 'tructured', materialize(2), 4) from numbers(3);
SELECT overlayUTF8(materialize('Spark SQL和CH'), 'tructured', 2, materialize(4)) from numbers(3);
SELECT overlayUTF8('Spark SQL和CH', materialize('tructured'), materialize(2), 4) from numbers(3);
SELECT overlayUTF8('Spark SQL和CH', materialize('tructured'), 2, materialize(4)) from numbers(3);
SELECT overlayUTF8('Spark SQL和CH', 'tructured', materialize(2), materialize(4)) from numbers(3);
SELECT overlayUTF8(materialize('Spark SQL和CH'), materialize('tructured'), materialize(2), materialize(4)) from numbers(3);