mirror of
https://github.com/ClickHouse/ClickHouse.git
synced 2024-11-24 08:32:02 +00:00
#214 fix conversion from fixed-string to string
This commit is contained in:
parent
1fedee71fb
commit
0ba72436db
@ -832,6 +832,8 @@ struct ReplaceStringImpl
|
||||
}
|
||||
}
|
||||
|
||||
/// Note: this function converts fixed-length strings to variable-length strings
|
||||
/// and each variable-length string should ends with zero byte.
|
||||
static void vector_fixed(const ColumnString::Chars_t & data,
|
||||
size_t n,
|
||||
const std::string & needle,
|
||||
@ -844,9 +846,9 @@ struct ReplaceStringImpl
|
||||
const UInt8 * end = pos + data.size();
|
||||
|
||||
ColumnString::Offset_t res_offset = 0;
|
||||
size_t size = data.size() / n;
|
||||
size_t count = data.size() / n;
|
||||
res_data.reserve(data.size());
|
||||
res_offsets.resize(size);
|
||||
res_offsets.resize(count);
|
||||
|
||||
/// The current index in the string array.
|
||||
size_t i = 0;
|
||||
@ -858,33 +860,45 @@ struct ReplaceStringImpl
|
||||
{
|
||||
const UInt8 * match = searcher.search(pos, end - pos);
|
||||
|
||||
/// Copy the data without changing
|
||||
res_data.resize(res_data.size() + (match - pos));
|
||||
memcpy(&res_data[res_offset], pos, match - pos);
|
||||
#define COPY_REST_OF_CURRENT_STRING() \
|
||||
do { \
|
||||
const size_t len = begin + n * (i + 1) - pos; \
|
||||
res_data.resize(res_data.size() + len + 1); \
|
||||
memcpy(&res_data[res_offset], pos, len); \
|
||||
res_offset += len; \
|
||||
res_data[res_offset++] = 0; \
|
||||
res_offsets[i] = res_offset; \
|
||||
pos = begin + n * (i + 1); \
|
||||
++i; \
|
||||
} while (false)
|
||||
|
||||
/// Let's determine which index it belongs to.
|
||||
while (i < size && begin + n * (i + 1) <= match)
|
||||
/// Copy skipped strings without any changes but
|
||||
/// add zero byte to the end of each string.
|
||||
while (i < count && begin + n * (i + 1) <= match)
|
||||
{
|
||||
res_offsets[i] = res_offset + ((begin + n * (i + 1)) - pos) + 1;
|
||||
++i;
|
||||
COPY_REST_OF_CURRENT_STRING();
|
||||
}
|
||||
res_offset += (match - pos);
|
||||
|
||||
/// If you have reached the end, it's time to stop
|
||||
if (i == size)
|
||||
if (i == count)
|
||||
break;
|
||||
|
||||
/// Copy unchanged part of current string.
|
||||
res_data.resize(res_data.size() + (match - pos));
|
||||
memcpy(&res_data[res_offset], pos, match - pos);
|
||||
res_offset += (match - pos);
|
||||
|
||||
/// Is it true that this line no longer needs to perform conversions.
|
||||
bool can_finish_current_string = false;
|
||||
|
||||
/// We check that the entry does not pass through the boundaries of strings.
|
||||
if (match + needle.size() - 1 < begin + n * (i + 1))
|
||||
if (match + needle.size() <= begin + n * (i + 1))
|
||||
{
|
||||
res_data.resize(res_data.size() + replacement.size());
|
||||
memcpy(&res_data[res_offset], replacement.data(), replacement.size());
|
||||
res_offset += replacement.size();
|
||||
pos = match + needle.size();
|
||||
if (replace_one)
|
||||
if (replace_one || pos == begin + n * (i + 1))
|
||||
can_finish_current_string = true;
|
||||
}
|
||||
else
|
||||
@ -895,17 +909,9 @@ struct ReplaceStringImpl
|
||||
|
||||
if (can_finish_current_string)
|
||||
{
|
||||
res_data.resize(res_data.size() + (begin + n * (i + 1) - pos));
|
||||
memcpy(&res_data[res_offset], pos, (begin + n * (i + 1) - pos));
|
||||
res_offset += (begin + n * (i + 1) - pos);
|
||||
res_offsets[i] = res_offset;
|
||||
pos = begin + n * (i + 1);
|
||||
COPY_REST_OF_CURRENT_STRING();
|
||||
}
|
||||
}
|
||||
|
||||
if (i < size)
|
||||
{
|
||||
res_offsets[i] = res_offset + ((begin + n * (i + 1)) - pos) + 1;
|
||||
#undef COPY_REST_OF_CURRENT_STRING
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2,3 +2,7 @@ bao ba*
|
||||
bar bar
|
||||
boa b*a
|
||||
foo f**
|
||||
54db0d43009d\0\0\0\0 54db0d43009d****
|
||||
fe2b58224766cf10 fe2b58224766cf10
|
||||
54db0d43009d\0\0\0\0 54db0d43009d****
|
||||
fe2b58224766cf10 fe2b58224766cf10
|
||||
|
@ -13,3 +13,14 @@ FROM test.replaceall
|
||||
ORDER BY str ASC;
|
||||
|
||||
DROP TABLE test.replaceall;
|
||||
|
||||
CREATE TABLE test.replaceall (date Date DEFAULT today(), fs FixedString(16)) ENGINE = MergeTree(date, (date, fs), 8192);
|
||||
INSERT INTO test (fs) VALUES
|
||||
('54db0d43009d\0\0\0\0'), ('fe2b58224766cf10'),
|
||||
('54db0d43009d\0\0\0\0'), ('fe2b58224766cf10');
|
||||
|
||||
SELECT fs, replaceAll(fs, '\0', '*')
|
||||
FROM test.replaceall
|
||||
ORDER BY fs ASC;
|
||||
|
||||
DROP TABLE test.replaceall;
|
||||
|
Loading…
Reference in New Issue
Block a user