mirror of
https://github.com/ClickHouse/ClickHouse.git
synced 2024-11-21 15:12:02 +00:00
dbms: fixed error with function positionCaseInsensitiveUTF8 [#METR-20054].
This commit is contained in:
parent
80fd8aa29b
commit
4c0b0e9c80
@ -26,10 +26,10 @@ inline bool isContinuationOctet(const UInt8 octet)
|
||||
return (octet & CONTINUATION_OCTET_MASK) == CONTINUATION_OCTET;
|
||||
}
|
||||
|
||||
/// moves `s` backward until either first non-continuation octet
|
||||
inline void syncBackward(const UInt8 * & s)
|
||||
/// moves `s` backward until either first non-continuation octet or begin
|
||||
inline void syncBackward(const UInt8 * & s, const UInt8 * const begin)
|
||||
{
|
||||
while (isContinuationOctet(*s))
|
||||
while (isContinuationOctet(*s) && s > begin)
|
||||
--s;
|
||||
}
|
||||
|
||||
|
@ -56,6 +56,35 @@ protected:
|
||||
static constexpr auto min_haystack_size_for_algorithm = 20000;
|
||||
const bool fallback; /// Нужно ли использовать fallback алгоритм.
|
||||
|
||||
|
||||
/// Эти функции эффективнее, чем соответствующие из libc, так как не учитывают локаль (что нам и надо).
|
||||
bool isascii(char c)
|
||||
{
|
||||
return static_cast<unsigned char>(c) < 0x80;
|
||||
}
|
||||
|
||||
bool isalpha(char c)
|
||||
{
|
||||
return (c >= 'a' && c <= 'z')
|
||||
|| (c >= 'A' && c <= 'Z');
|
||||
}
|
||||
|
||||
/// Работает корректно только при условии isalpha.
|
||||
char tolower(char c)
|
||||
{
|
||||
return c | 0x20;
|
||||
}
|
||||
|
||||
char toupper(char c)
|
||||
{
|
||||
return c & (~0x20);
|
||||
}
|
||||
|
||||
char alternate(char c)
|
||||
{
|
||||
return c ^ 0x20;
|
||||
}
|
||||
|
||||
public:
|
||||
/** haystack_size_hint - ожидаемый суммарный размер haystack при вызовах search. Можно не указывать.
|
||||
* Если указать его достаточно маленьким, то будет использован fallback алгоритм,
|
||||
@ -64,9 +93,8 @@ public:
|
||||
VolnitskyBase(const char * const needle, const size_t needle_size, size_t haystack_size_hint = 0)
|
||||
: needle{reinterpret_cast<const UInt8 *>(needle)}, needle_size{needle_size},
|
||||
fallback{
|
||||
needle_size < 2 * sizeof(ngram_t) or needle_size >= std::numeric_limits<offset_t>::max() or
|
||||
(haystack_size_hint and haystack_size_hint < min_haystack_size_for_algorithm)
|
||||
}
|
||||
needle_size < 2 * sizeof(ngram_t) || needle_size >= std::numeric_limits<offset_t>::max() ||
|
||||
(haystack_size_hint && haystack_size_hint < min_haystack_size_for_algorithm)}
|
||||
{
|
||||
if (fallback)
|
||||
return;
|
||||
@ -75,7 +103,7 @@ public:
|
||||
|
||||
/// int is used here because unsigned can't be used with condition like `i >= 0`, unsigned always >= 0
|
||||
for (auto i = static_cast<int>(needle_size - sizeof(ngram_t)); i >= 0; --i)
|
||||
self().putNGram(this->needle + i, i + 1);
|
||||
self().putNGram(this->needle + i, i + 1, this->needle);
|
||||
}
|
||||
|
||||
|
||||
@ -134,6 +162,54 @@ protected:
|
||||
|
||||
hash[cell_num] = offset;
|
||||
}
|
||||
|
||||
void putNGramASCIICaseInsensitive(const UInt8 * const pos, const int offset)
|
||||
{
|
||||
union
|
||||
{
|
||||
ngram_t n;
|
||||
|
||||
struct Chars
|
||||
{
|
||||
UInt8 c0;
|
||||
UInt8 c1;
|
||||
} chars;
|
||||
};
|
||||
|
||||
n = toNGram(pos);
|
||||
|
||||
const auto c0_al = isalpha(chars.c0);
|
||||
const auto c1_al = isalpha(chars.c1);
|
||||
|
||||
if (c0_al && c1_al)
|
||||
{
|
||||
/// 4 combinations: AB, aB, Ab, ab
|
||||
putNGramBase(n, offset);
|
||||
chars.c0 = alternate(chars.c0);
|
||||
putNGramBase(n, offset);
|
||||
chars.c1 = alternate(chars.c1);
|
||||
putNGramBase(n, offset);
|
||||
chars.c0 = alternate(chars.c0);
|
||||
putNGramBase(n, offset);
|
||||
}
|
||||
else if (c0_al)
|
||||
{
|
||||
/// 2 combinations: A1, a1
|
||||
putNGramBase(n, offset);
|
||||
chars.c0 = alternate(chars.c0);
|
||||
putNGramBase(n, offset);
|
||||
}
|
||||
else if (c1_al)
|
||||
{
|
||||
/// 2 combinations: 0B, 0b
|
||||
putNGramBase(n, offset);
|
||||
chars.c1 = alternate(chars.c1);
|
||||
putNGramBase(n, offset);
|
||||
}
|
||||
else
|
||||
/// 1 combination: 01
|
||||
putNGramBase(n, offset);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@ -148,7 +224,7 @@ template <bool ASCII> struct VolnitskyImpl<true, ASCII> : VolnitskyBase<Volnitsk
|
||||
{
|
||||
}
|
||||
|
||||
void putNGram(const UInt8 * const pos, const int offset)
|
||||
void putNGram(const UInt8 * const pos, const int offset, const UInt8 * const begin)
|
||||
{
|
||||
this->putNGramBase(this->toNGram(pos), offset);
|
||||
}
|
||||
@ -175,54 +251,9 @@ template <> struct VolnitskyImpl<false, true> : VolnitskyBase<VolnitskyImpl<fals
|
||||
{
|
||||
}
|
||||
|
||||
void putNGram(const UInt8 * const pos, const int offset)
|
||||
void putNGram(const UInt8 * const pos, const int offset, const UInt8 * const begin)
|
||||
{
|
||||
union {
|
||||
ngram_t n;
|
||||
UInt8 c[2];
|
||||
};
|
||||
|
||||
n = toNGram(pos);
|
||||
const auto c0_alpha = std::isalpha(c[0]);
|
||||
const auto c1_alpha = std::isalpha(c[1]);
|
||||
|
||||
if (c0_alpha && c1_alpha)
|
||||
{
|
||||
/// 4 combinations: AB, aB, Ab, ab
|
||||
c[0] = std::tolower(c[0]);
|
||||
c[1] = std::tolower(c[1]);
|
||||
putNGramBase(n, offset);
|
||||
|
||||
c[0] = std::toupper(c[0]);
|
||||
putNGramBase(n, offset);
|
||||
|
||||
c[1] = std::toupper(c[1]);
|
||||
putNGramBase(n, offset);
|
||||
|
||||
c[0] = std::tolower(c[0]);
|
||||
putNGramBase(n, offset);
|
||||
}
|
||||
else if (c0_alpha)
|
||||
{
|
||||
/// 2 combinations: A1, a1
|
||||
c[0] = std::tolower(c[0]);
|
||||
putNGramBase(n, offset);
|
||||
|
||||
c[0] = std::toupper(c[0]);
|
||||
putNGramBase(n, offset);
|
||||
}
|
||||
else if (c1_alpha)
|
||||
{
|
||||
/// 2 combinations: 0B, 0b
|
||||
c[1] = std::tolower(c[1]);
|
||||
putNGramBase(n, offset);
|
||||
|
||||
c[1] = std::toupper(c[1]);
|
||||
putNGramBase(n, offset);
|
||||
}
|
||||
else
|
||||
/// 1 combination: 01
|
||||
putNGramBase(n, offset);
|
||||
putNGramASCIICaseInsensitive(pos, offset);
|
||||
}
|
||||
|
||||
bool compare(const UInt8 * const pos) const
|
||||
@ -246,70 +277,47 @@ template <> struct VolnitskyImpl<false, false> : VolnitskyBase<VolnitskyImpl<fal
|
||||
{
|
||||
}
|
||||
|
||||
void putNGram(const UInt8 * const pos, const int offset)
|
||||
void putNGram(const UInt8 * const pos, const int offset, const UInt8 * const begin)
|
||||
{
|
||||
union
|
||||
{
|
||||
ngram_t n;
|
||||
UInt8 c[2];
|
||||
|
||||
struct Chars
|
||||
{
|
||||
UInt8 c0;
|
||||
UInt8 c1;
|
||||
} chars;
|
||||
};
|
||||
|
||||
n = toNGram(pos);
|
||||
|
||||
if (isascii(c[0]) && isascii(c[1]))
|
||||
if (isascii(chars.c0) && isascii(chars.c1))
|
||||
{
|
||||
const auto c0_al = std::isalpha(c[0]);
|
||||
const auto c1_al = std::isalpha(c[1]);
|
||||
|
||||
if (c0_al && c1_al)
|
||||
{
|
||||
/// 4 combinations: AB, aB, Ab, ab
|
||||
c[0] = std::tolower(c[0]);
|
||||
c[1] = std::tolower(c[1]);
|
||||
putNGramBase(n, offset);
|
||||
|
||||
c[0] = std::toupper(c[0]);
|
||||
putNGramBase(n, offset);
|
||||
|
||||
c[1] = std::toupper(c[1]);
|
||||
putNGramBase(n, offset);
|
||||
|
||||
c[0] = std::tolower(c[0]);
|
||||
putNGramBase(n, offset);
|
||||
}
|
||||
else if (c0_al)
|
||||
{
|
||||
/// 2 combinations: A1, a1
|
||||
c[0] = std::tolower(c[0]);
|
||||
putNGramBase(n, offset);
|
||||
|
||||
c[0] = std::toupper(c[0]);
|
||||
putNGramBase(n, offset);
|
||||
}
|
||||
else if (c1_al)
|
||||
{
|
||||
/// 2 combinations: 0B, 0b
|
||||
c[1] = std::tolower(c[1]);
|
||||
putNGramBase(n, offset);
|
||||
|
||||
c[1] = std::toupper(c[1]);
|
||||
putNGramBase(n, offset);
|
||||
}
|
||||
else
|
||||
/// 1 combination: 01
|
||||
putNGramBase(n, offset);
|
||||
putNGramASCIICaseInsensitive(pos, offset);
|
||||
}
|
||||
else
|
||||
{
|
||||
/** n-грам (в случае n = 2)
|
||||
* может быть целиком расположен внутри одной кодовой точки,
|
||||
* либо пересекаться с двумя кодовыми точками.
|
||||
*
|
||||
* В первом случае, нужно рассматривать до двух альтернатив - эта кодовая точка в верхнем и нижнем регистре,
|
||||
* а во втором случае - до четырёх альтернатив - фрагменты двух кодовых точек во всех комбинациях регистров.
|
||||
*
|
||||
* При этом не учитывается зависимость перевода между регистрами от локали (пример - турецкие Ii)
|
||||
* а также композиция/декомпозиция и другие особенности.
|
||||
*/
|
||||
|
||||
using Seq = UInt8[6];
|
||||
|
||||
static const Poco::UTF8Encoding utf8;
|
||||
|
||||
if (UTF8::isContinuationOctet(c[1]))
|
||||
if (UTF8::isContinuationOctet(chars.c1))
|
||||
{
|
||||
/// ngram is inside a sequence
|
||||
auto seq_pos = pos;
|
||||
UTF8::syncBackward(seq_pos);
|
||||
UTF8::syncBackward(seq_pos, begin);
|
||||
|
||||
const auto u32 = utf8.convert(seq_pos);
|
||||
const auto l_u32 = Poco::Unicode::toLower(u32);
|
||||
@ -327,14 +335,14 @@ template <> struct VolnitskyImpl<false, false> : VolnitskyBase<VolnitskyImpl<fal
|
||||
|
||||
/// put ngram from lowercase
|
||||
utf8.convert(l_u32, seq, sizeof(seq));
|
||||
c[0] = seq[seq_ngram_offset];
|
||||
c[1] = seq[seq_ngram_offset + 1];
|
||||
chars.c0 = seq[seq_ngram_offset];
|
||||
chars.c1 = seq[seq_ngram_offset + 1];
|
||||
putNGramBase(n, offset);
|
||||
|
||||
/// put ngram for uppercase
|
||||
utf8.convert(u_u32, seq, sizeof(seq));
|
||||
c[0] = seq[seq_ngram_offset];
|
||||
c[1] = seq[seq_ngram_offset + 1];
|
||||
chars.c0 = seq[seq_ngram_offset];
|
||||
chars.c1 = seq[seq_ngram_offset + 1];
|
||||
putNGramBase(n, offset);
|
||||
}
|
||||
}
|
||||
@ -343,7 +351,9 @@ template <> struct VolnitskyImpl<false, false> : VolnitskyBase<VolnitskyImpl<fal
|
||||
/// ngram is on the boundary of two sequences
|
||||
/// first sequence may start before u_pos if it is not ASCII
|
||||
auto first_seq_pos = pos;
|
||||
UTF8::syncBackward(first_seq_pos);
|
||||
UTF8::syncBackward(first_seq_pos, begin);
|
||||
/// where is the given ngram in respect to the first UTF-8 sequence start?
|
||||
const auto seq_ngram_offset = pos - first_seq_pos;
|
||||
|
||||
const auto first_u32 = utf8.convert(first_seq_pos);
|
||||
const auto first_l_u32 = Poco::Unicode::toLower(first_u32);
|
||||
@ -352,13 +362,15 @@ template <> struct VolnitskyImpl<false, false> : VolnitskyBase<VolnitskyImpl<fal
|
||||
/// second sequence always start immediately after u_pos
|
||||
auto second_seq_pos = pos + 1;
|
||||
|
||||
const auto second_u32 = utf8.convert(second_seq_pos);
|
||||
const auto second_u32 = utf8.convert(second_seq_pos); /// TODO This assumes valid UTF-8 or zero byte after needle.
|
||||
const auto second_l_u32 = Poco::Unicode::toLower(second_u32);
|
||||
const auto second_u_u32 = Poco::Unicode::toUpper(second_u32);
|
||||
|
||||
/// both symbols are case-independent
|
||||
if (first_l_u32 == first_u_u32 && second_l_u32 == second_u_u32)
|
||||
{
|
||||
putNGramBase(n, offset);
|
||||
}
|
||||
else if (first_l_u32 == first_u_u32)
|
||||
{
|
||||
/// first symbol is case-independent
|
||||
@ -366,64 +378,80 @@ template <> struct VolnitskyImpl<false, false> : VolnitskyBase<VolnitskyImpl<fal
|
||||
|
||||
/// put ngram for lowercase
|
||||
utf8.convert(second_l_u32, seq, sizeof(seq));
|
||||
c[1] = seq[0];
|
||||
chars.c1 = seq[0];
|
||||
putNGramBase(n, offset);
|
||||
|
||||
/// put ngram from uppercase
|
||||
/// put ngram from uppercase, if it is different
|
||||
utf8.convert(second_u_u32, seq, sizeof(seq));
|
||||
c[1] = seq[0];
|
||||
putNGramBase(n, offset);
|
||||
if (chars.c1 != seq[0])
|
||||
{
|
||||
chars.c1 = seq[0];
|
||||
putNGramBase(n, offset);
|
||||
}
|
||||
}
|
||||
else if (second_l_u32 == second_u_u32)
|
||||
{
|
||||
/// second symbol is case-independent
|
||||
|
||||
/// where is the given ngram in respect to the first UTF-8 sequence start?
|
||||
const auto seq_ngram_offset = pos - first_seq_pos;
|
||||
|
||||
Seq seq;
|
||||
|
||||
/// put ngram for lowercase
|
||||
utf8.convert(second_l_u32, seq, sizeof(seq));
|
||||
c[0] = seq[seq_ngram_offset];
|
||||
utf8.convert(first_l_u32, seq, sizeof(seq));
|
||||
chars.c0 = seq[seq_ngram_offset];
|
||||
putNGramBase(n, offset);
|
||||
|
||||
/// put ngram for uppercase
|
||||
utf8.convert(second_u_u32, seq, sizeof(seq));
|
||||
c[0] = seq[seq_ngram_offset];
|
||||
putNGramBase(n, offset);
|
||||
/// put ngram for uppercase, if it is different
|
||||
utf8.convert(first_u_u32, seq, sizeof(seq));
|
||||
if (chars.c0 != seq[seq_ngram_offset])
|
||||
{
|
||||
chars.c0 = seq[seq_ngram_offset];
|
||||
putNGramBase(n, offset);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/// where is the given ngram in respect to the first UTF-8 sequence start?
|
||||
const auto seq_ngram_offset = pos - first_seq_pos;
|
||||
|
||||
Seq first_l_seq, first_u_seq, second_l_seq, second_u_seq;
|
||||
Seq first_l_seq;
|
||||
Seq first_u_seq;
|
||||
Seq second_l_seq;
|
||||
Seq second_u_seq;
|
||||
|
||||
utf8.convert(first_l_u32, first_l_seq, sizeof(first_l_seq));
|
||||
utf8.convert(first_u_u32, first_u_seq, sizeof(first_u_seq));
|
||||
utf8.convert(second_l_u32, second_l_seq, sizeof(second_l_seq));
|
||||
utf8.convert(second_u_u32, second_u_seq, sizeof(second_u_seq));
|
||||
|
||||
auto c0l = first_l_seq[seq_ngram_offset];
|
||||
auto c0u = first_u_seq[seq_ngram_offset];
|
||||
auto c1l = second_l_seq[0];
|
||||
auto c1u = second_u_seq[0];
|
||||
|
||||
/// ngram for ll
|
||||
c[0] = first_l_seq[seq_ngram_offset];
|
||||
c[1] = second_l_seq[0];
|
||||
chars.c0 = c0l;
|
||||
chars.c1 = c1l;
|
||||
putNGramBase(n, offset);
|
||||
|
||||
/// ngram for lU
|
||||
c[0] = first_l_seq[seq_ngram_offset];
|
||||
c[1] = second_u_seq[0];
|
||||
putNGramBase(n, offset);
|
||||
if (c0l != c0u)
|
||||
{
|
||||
/// ngram for Ul
|
||||
chars.c0 = c0u;
|
||||
chars.c1 = c1l;
|
||||
putNGramBase(n, offset);
|
||||
}
|
||||
|
||||
/// ngram for Ul
|
||||
c[0] = first_u_seq[seq_ngram_offset];
|
||||
c[1] = second_l_seq[0];
|
||||
putNGramBase(n, offset);
|
||||
if (c1l != c1u)
|
||||
{
|
||||
/// ngram for lU
|
||||
chars.c0 = c0l;
|
||||
chars.c1 = c1u;
|
||||
putNGramBase(n, offset);
|
||||
}
|
||||
|
||||
/// ngram for UU
|
||||
c[0] = first_u_seq[seq_ngram_offset];
|
||||
c[1] = second_u_seq[0];
|
||||
putNGramBase(n, offset);
|
||||
if (c0l != c0u && c1l != c1u)
|
||||
{
|
||||
/// ngram for UU
|
||||
chars.c0 = c0u;
|
||||
chars.c1 = c1u;
|
||||
putNGramBase(n, offset);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -251,6 +251,43 @@ public:
|
||||
};
|
||||
|
||||
|
||||
class FunctionRowNumberInBlock : public IFunction
|
||||
{
|
||||
public:
|
||||
static constexpr auto name = "rowNumberInBlock";
|
||||
static IFunction * create(const Context & context) { return new FunctionRowNumberInBlock; }
|
||||
|
||||
/// Получить имя функции.
|
||||
String getName() const override
|
||||
{
|
||||
return name;
|
||||
}
|
||||
|
||||
/// Получить тип результата по типам аргументов. Если функция неприменима для данных аргументов - кинуть исключение.
|
||||
DataTypePtr getReturnType(const DataTypes & arguments) const override
|
||||
{
|
||||
if (!arguments.empty())
|
||||
throw Exception("Number of arguments for function " + getName() + " doesn't match: passed "
|
||||
+ toString(arguments.size()) + ", should be 0.",
|
||||
ErrorCodes::NUMBER_OF_ARGUMENTS_DOESNT_MATCH);
|
||||
|
||||
return new DataTypeUInt64;
|
||||
}
|
||||
|
||||
/// Выполнить функцию над блоком.
|
||||
void execute(Block & block, const ColumnNumbers & arguments, size_t result) override
|
||||
{
|
||||
size_t size = block.rowsInFirstColumn();
|
||||
auto column = new ColumnUInt64;
|
||||
block.getByPosition(result).column = column;
|
||||
auto & data = column->getData();
|
||||
data.resize(size);
|
||||
for (size_t i = 0; i < size; ++i)
|
||||
data[i] = i;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
class FunctionSleep : public IFunction
|
||||
{
|
||||
public:
|
||||
|
@ -380,6 +380,7 @@ void registerFunctionsMiscellaneous(FunctionFactory & factory)
|
||||
factory.registerFunction<FunctionVisibleWidth>();
|
||||
factory.registerFunction<FunctionToTypeName>();
|
||||
factory.registerFunction<FunctionBlockSize>();
|
||||
factory.registerFunction<FunctionRowNumberInBlock>();
|
||||
factory.registerFunction<FunctionSleep>();
|
||||
factory.registerFunction<FunctionMaterialize>();
|
||||
factory.registerFunction<FunctionIgnore>();
|
||||
|
@ -0,0 +1,92 @@
|
||||
1
|
||||
2
|
||||
3
|
||||
4
|
||||
5
|
||||
6
|
||||
7
|
||||
8
|
||||
9
|
||||
10
|
||||
11
|
||||
12
|
||||
13
|
||||
14
|
||||
15
|
||||
16
|
||||
17
|
||||
18
|
||||
19
|
||||
20
|
||||
21
|
||||
22
|
||||
23
|
||||
1
|
||||
2
|
||||
3
|
||||
4
|
||||
5
|
||||
6
|
||||
7
|
||||
8
|
||||
9
|
||||
10
|
||||
11
|
||||
12
|
||||
13
|
||||
14
|
||||
15
|
||||
16
|
||||
17
|
||||
18
|
||||
19
|
||||
20
|
||||
21
|
||||
22
|
||||
23
|
||||
1
|
||||
2
|
||||
3
|
||||
4
|
||||
5
|
||||
6
|
||||
7
|
||||
8
|
||||
9
|
||||
10
|
||||
11
|
||||
12
|
||||
13
|
||||
14
|
||||
15
|
||||
16
|
||||
17
|
||||
18
|
||||
19
|
||||
20
|
||||
21
|
||||
22
|
||||
23
|
||||
1
|
||||
2
|
||||
3
|
||||
4
|
||||
5
|
||||
6
|
||||
7
|
||||
8
|
||||
9
|
||||
10
|
||||
11
|
||||
12
|
||||
13
|
||||
14
|
||||
15
|
||||
16
|
||||
17
|
||||
18
|
||||
19
|
||||
20
|
||||
21
|
||||
22
|
||||
23
|
@ -0,0 +1,95 @@
|
||||
SELECT positionCaseInsensitiveUTF8(concat('иголка.ру', arrayStringConcat(arrayMap(x -> ' ', range(20000)))), 'иголка.ру') AS res;
|
||||
SELECT positionCaseInsensitiveUTF8(concat(' иголка.ру', arrayStringConcat(arrayMap(x -> ' ', range(20000)))), 'иголка.ру') AS res;
|
||||
SELECT positionCaseInsensitiveUTF8(concat(' иголка.ру', arrayStringConcat(arrayMap(x -> ' ', range(20000)))), 'иголка.ру') AS res;
|
||||
SELECT positionCaseInsensitiveUTF8(concat(' иголка.ру', arrayStringConcat(arrayMap(x -> ' ', range(20000)))), 'иголка.ру') AS res;
|
||||
SELECT positionCaseInsensitiveUTF8(concat(' иголка.ру', arrayStringConcat(arrayMap(x -> ' ', range(20000)))), 'иголка.ру') AS res;
|
||||
SELECT positionCaseInsensitiveUTF8(concat(' иголка.ру', arrayStringConcat(arrayMap(x -> ' ', range(20000)))), 'иголка.ру') AS res;
|
||||
SELECT positionCaseInsensitiveUTF8(concat(' иголка.ру', arrayStringConcat(arrayMap(x -> ' ', range(20000)))), 'иголка.ру') AS res;
|
||||
SELECT positionCaseInsensitiveUTF8(concat(' иголка.ру', arrayStringConcat(arrayMap(x -> ' ', range(20000)))), 'иголка.ру') AS res;
|
||||
SELECT positionCaseInsensitiveUTF8(concat(' иголка.ру', arrayStringConcat(arrayMap(x -> ' ', range(20000)))), 'иголка.ру') AS res;
|
||||
SELECT positionCaseInsensitiveUTF8(concat(' иголка.ру', arrayStringConcat(arrayMap(x -> ' ', range(20000)))), 'иголка.ру') AS res;
|
||||
SELECT positionCaseInsensitiveUTF8(concat(' иголка.ру', arrayStringConcat(arrayMap(x -> ' ', range(20000)))), 'иголка.ру') AS res;
|
||||
SELECT positionCaseInsensitiveUTF8(concat(' иголка.ру', arrayStringConcat(arrayMap(x -> ' ', range(20000)))), 'иголка.ру') AS res;
|
||||
SELECT positionCaseInsensitiveUTF8(concat(' иголка.ру', arrayStringConcat(arrayMap(x -> ' ', range(20000)))), 'иголка.ру') AS res;
|
||||
SELECT positionCaseInsensitiveUTF8(concat(' иголка.ру', arrayStringConcat(arrayMap(x -> ' ', range(20000)))), 'иголка.ру') AS res;
|
||||
SELECT positionCaseInsensitiveUTF8(concat(' иголка.ру', arrayStringConcat(arrayMap(x -> ' ', range(20000)))), 'иголка.ру') AS res;
|
||||
SELECT positionCaseInsensitiveUTF8(concat(' иголка.ру', arrayStringConcat(arrayMap(x -> ' ', range(20000)))), 'иголка.ру') AS res;
|
||||
SELECT positionCaseInsensitiveUTF8(concat(' иголка.ру', arrayStringConcat(arrayMap(x -> ' ', range(20000)))), 'иголка.ру') AS res;
|
||||
SELECT positionCaseInsensitiveUTF8(concat(' иголка.ру', arrayStringConcat(arrayMap(x -> ' ', range(20000)))), 'иголка.ру') AS res;
|
||||
SELECT positionCaseInsensitiveUTF8(concat(' иголка.ру', arrayStringConcat(arrayMap(x -> ' ', range(20000)))), 'иголка.ру') AS res;
|
||||
SELECT positionCaseInsensitiveUTF8(concat(' иголка.ру', arrayStringConcat(arrayMap(x -> ' ', range(20000)))), 'иголка.ру') AS res;
|
||||
SELECT positionCaseInsensitiveUTF8(concat(' иголка.ру', arrayStringConcat(arrayMap(x -> ' ', range(20000)))), 'иголка.ру') AS res;
|
||||
SELECT positionCaseInsensitiveUTF8(concat(' иголка.ру', arrayStringConcat(arrayMap(x -> ' ', range(20000)))), 'иголка.ру') AS res;
|
||||
SELECT positionCaseInsensitiveUTF8(concat(' иголка.ру', arrayStringConcat(arrayMap(x -> ' ', range(20000)))), 'иголка.ру') AS res;
|
||||
|
||||
SELECT positionCaseInsensitive(concat('иголка.ру', arrayStringConcat(arrayMap(x -> ' ', range(20000)))), 'иголка.ру') AS res;
|
||||
SELECT positionCaseInsensitive(concat(' иголка.ру', arrayStringConcat(arrayMap(x -> ' ', range(20000)))), 'иголка.ру') AS res;
|
||||
SELECT positionCaseInsensitive(concat(' иголка.ру', arrayStringConcat(arrayMap(x -> ' ', range(20000)))), 'иголка.ру') AS res;
|
||||
SELECT positionCaseInsensitive(concat(' иголка.ру', arrayStringConcat(arrayMap(x -> ' ', range(20000)))), 'иголка.ру') AS res;
|
||||
SELECT positionCaseInsensitive(concat(' иголка.ру', arrayStringConcat(arrayMap(x -> ' ', range(20000)))), 'иголка.ру') AS res;
|
||||
SELECT positionCaseInsensitive(concat(' иголка.ру', arrayStringConcat(arrayMap(x -> ' ', range(20000)))), 'иголка.ру') AS res;
|
||||
SELECT positionCaseInsensitive(concat(' иголка.ру', arrayStringConcat(arrayMap(x -> ' ', range(20000)))), 'иголка.ру') AS res;
|
||||
SELECT positionCaseInsensitive(concat(' иголка.ру', arrayStringConcat(arrayMap(x -> ' ', range(20000)))), 'иголка.ру') AS res;
|
||||
SELECT positionCaseInsensitive(concat(' иголка.ру', arrayStringConcat(arrayMap(x -> ' ', range(20000)))), 'иголка.ру') AS res;
|
||||
SELECT positionCaseInsensitive(concat(' иголка.ру', arrayStringConcat(arrayMap(x -> ' ', range(20000)))), 'иголка.ру') AS res;
|
||||
SELECT positionCaseInsensitive(concat(' иголка.ру', arrayStringConcat(arrayMap(x -> ' ', range(20000)))), 'иголка.ру') AS res;
|
||||
SELECT positionCaseInsensitive(concat(' иголка.ру', arrayStringConcat(arrayMap(x -> ' ', range(20000)))), 'иголка.ру') AS res;
|
||||
SELECT positionCaseInsensitive(concat(' иголка.ру', arrayStringConcat(arrayMap(x -> ' ', range(20000)))), 'иголка.ру') AS res;
|
||||
SELECT positionCaseInsensitive(concat(' иголка.ру', arrayStringConcat(arrayMap(x -> ' ', range(20000)))), 'иголка.ру') AS res;
|
||||
SELECT positionCaseInsensitive(concat(' иголка.ру', arrayStringConcat(arrayMap(x -> ' ', range(20000)))), 'иголка.ру') AS res;
|
||||
SELECT positionCaseInsensitive(concat(' иголка.ру', arrayStringConcat(arrayMap(x -> ' ', range(20000)))), 'иголка.ру') AS res;
|
||||
SELECT positionCaseInsensitive(concat(' иголка.ру', arrayStringConcat(arrayMap(x -> ' ', range(20000)))), 'иголка.ру') AS res;
|
||||
SELECT positionCaseInsensitive(concat(' иголка.ру', arrayStringConcat(arrayMap(x -> ' ', range(20000)))), 'иголка.ру') AS res;
|
||||
SELECT positionCaseInsensitive(concat(' иголка.ру', arrayStringConcat(arrayMap(x -> ' ', range(20000)))), 'иголка.ру') AS res;
|
||||
SELECT positionCaseInsensitive(concat(' иголка.ру', arrayStringConcat(arrayMap(x -> ' ', range(20000)))), 'иголка.ру') AS res;
|
||||
SELECT positionCaseInsensitive(concat(' иголка.ру', arrayStringConcat(arrayMap(x -> ' ', range(20000)))), 'иголка.ру') AS res;
|
||||
SELECT positionCaseInsensitive(concat(' иголка.ру', arrayStringConcat(arrayMap(x -> ' ', range(20000)))), 'иголка.ру') AS res;
|
||||
SELECT positionCaseInsensitive(concat(' иголка.ру', arrayStringConcat(arrayMap(x -> ' ', range(20000)))), 'иголка.ру') AS res;
|
||||
|
||||
SELECT positionUTF8(concat('иголка.ру', arrayStringConcat(arrayMap(x -> ' ', range(20000)))), 'иголка.ру') AS res;
|
||||
SELECT positionUTF8(concat(' иголка.ру', arrayStringConcat(arrayMap(x -> ' ', range(20000)))), 'иголка.ру') AS res;
|
||||
SELECT positionUTF8(concat(' иголка.ру', arrayStringConcat(arrayMap(x -> ' ', range(20000)))), 'иголка.ру') AS res;
|
||||
SELECT positionUTF8(concat(' иголка.ру', arrayStringConcat(arrayMap(x -> ' ', range(20000)))), 'иголка.ру') AS res;
|
||||
SELECT positionUTF8(concat(' иголка.ру', arrayStringConcat(arrayMap(x -> ' ', range(20000)))), 'иголка.ру') AS res;
|
||||
SELECT positionUTF8(concat(' иголка.ру', arrayStringConcat(arrayMap(x -> ' ', range(20000)))), 'иголка.ру') AS res;
|
||||
SELECT positionUTF8(concat(' иголка.ру', arrayStringConcat(arrayMap(x -> ' ', range(20000)))), 'иголка.ру') AS res;
|
||||
SELECT positionUTF8(concat(' иголка.ру', arrayStringConcat(arrayMap(x -> ' ', range(20000)))), 'иголка.ру') AS res;
|
||||
SELECT positionUTF8(concat(' иголка.ру', arrayStringConcat(arrayMap(x -> ' ', range(20000)))), 'иголка.ру') AS res;
|
||||
SELECT positionUTF8(concat(' иголка.ру', arrayStringConcat(arrayMap(x -> ' ', range(20000)))), 'иголка.ру') AS res;
|
||||
SELECT positionUTF8(concat(' иголка.ру', arrayStringConcat(arrayMap(x -> ' ', range(20000)))), 'иголка.ру') AS res;
|
||||
SELECT positionUTF8(concat(' иголка.ру', arrayStringConcat(arrayMap(x -> ' ', range(20000)))), 'иголка.ру') AS res;
|
||||
SELECT positionUTF8(concat(' иголка.ру', arrayStringConcat(arrayMap(x -> ' ', range(20000)))), 'иголка.ру') AS res;
|
||||
SELECT positionUTF8(concat(' иголка.ру', arrayStringConcat(arrayMap(x -> ' ', range(20000)))), 'иголка.ру') AS res;
|
||||
SELECT positionUTF8(concat(' иголка.ру', arrayStringConcat(arrayMap(x -> ' ', range(20000)))), 'иголка.ру') AS res;
|
||||
SELECT positionUTF8(concat(' иголка.ру', arrayStringConcat(arrayMap(x -> ' ', range(20000)))), 'иголка.ру') AS res;
|
||||
SELECT positionUTF8(concat(' иголка.ру', arrayStringConcat(arrayMap(x -> ' ', range(20000)))), 'иголка.ру') AS res;
|
||||
SELECT positionUTF8(concat(' иголка.ру', arrayStringConcat(arrayMap(x -> ' ', range(20000)))), 'иголка.ру') AS res;
|
||||
SELECT positionUTF8(concat(' иголка.ру', arrayStringConcat(arrayMap(x -> ' ', range(20000)))), 'иголка.ру') AS res;
|
||||
SELECT positionUTF8(concat(' иголка.ру', arrayStringConcat(arrayMap(x -> ' ', range(20000)))), 'иголка.ру') AS res;
|
||||
SELECT positionUTF8(concat(' иголка.ру', arrayStringConcat(arrayMap(x -> ' ', range(20000)))), 'иголка.ру') AS res;
|
||||
SELECT positionUTF8(concat(' иголка.ру', arrayStringConcat(arrayMap(x -> ' ', range(20000)))), 'иголка.ру') AS res;
|
||||
SELECT positionUTF8(concat(' иголка.ру', arrayStringConcat(arrayMap(x -> ' ', range(20000)))), 'иголка.ру') AS res;
|
||||
|
||||
SELECT position(concat('иголка.ру', arrayStringConcat(arrayMap(x -> ' ', range(20000)))), 'иголка.ру') AS res;
|
||||
SELECT position(concat(' иголка.ру', arrayStringConcat(arrayMap(x -> ' ', range(20000)))), 'иголка.ру') AS res;
|
||||
SELECT position(concat(' иголка.ру', arrayStringConcat(arrayMap(x -> ' ', range(20000)))), 'иголка.ру') AS res;
|
||||
SELECT position(concat(' иголка.ру', arrayStringConcat(arrayMap(x -> ' ', range(20000)))), 'иголка.ру') AS res;
|
||||
SELECT position(concat(' иголка.ру', arrayStringConcat(arrayMap(x -> ' ', range(20000)))), 'иголка.ру') AS res;
|
||||
SELECT position(concat(' иголка.ру', arrayStringConcat(arrayMap(x -> ' ', range(20000)))), 'иголка.ру') AS res;
|
||||
SELECT position(concat(' иголка.ру', arrayStringConcat(arrayMap(x -> ' ', range(20000)))), 'иголка.ру') AS res;
|
||||
SELECT position(concat(' иголка.ру', arrayStringConcat(arrayMap(x -> ' ', range(20000)))), 'иголка.ру') AS res;
|
||||
SELECT position(concat(' иголка.ру', arrayStringConcat(arrayMap(x -> ' ', range(20000)))), 'иголка.ру') AS res;
|
||||
SELECT position(concat(' иголка.ру', arrayStringConcat(arrayMap(x -> ' ', range(20000)))), 'иголка.ру') AS res;
|
||||
SELECT position(concat(' иголка.ру', arrayStringConcat(arrayMap(x -> ' ', range(20000)))), 'иголка.ру') AS res;
|
||||
SELECT position(concat(' иголка.ру', arrayStringConcat(arrayMap(x -> ' ', range(20000)))), 'иголка.ру') AS res;
|
||||
SELECT position(concat(' иголка.ру', arrayStringConcat(arrayMap(x -> ' ', range(20000)))), 'иголка.ру') AS res;
|
||||
SELECT position(concat(' иголка.ру', arrayStringConcat(arrayMap(x -> ' ', range(20000)))), 'иголка.ру') AS res;
|
||||
SELECT position(concat(' иголка.ру', arrayStringConcat(arrayMap(x -> ' ', range(20000)))), 'иголка.ру') AS res;
|
||||
SELECT position(concat(' иголка.ру', arrayStringConcat(arrayMap(x -> ' ', range(20000)))), 'иголка.ру') AS res;
|
||||
SELECT position(concat(' иголка.ру', arrayStringConcat(arrayMap(x -> ' ', range(20000)))), 'иголка.ру') AS res;
|
||||
SELECT position(concat(' иголка.ру', arrayStringConcat(arrayMap(x -> ' ', range(20000)))), 'иголка.ру') AS res;
|
||||
SELECT position(concat(' иголка.ру', arrayStringConcat(arrayMap(x -> ' ', range(20000)))), 'иголка.ру') AS res;
|
||||
SELECT position(concat(' иголка.ру', arrayStringConcat(arrayMap(x -> ' ', range(20000)))), 'иголка.ру') AS res;
|
||||
SELECT position(concat(' иголка.ру', arrayStringConcat(arrayMap(x -> ' ', range(20000)))), 'иголка.ру') AS res;
|
||||
SELECT position(concat(' иголка.ру', arrayStringConcat(arrayMap(x -> ' ', range(20000)))), 'иголка.ру') AS res;
|
||||
SELECT position(concat(' иголка.ру', arrayStringConcat(arrayMap(x -> ' ', range(20000)))), 'иголка.ру') AS res;
|
Loading…
Reference in New Issue
Block a user