mirror of
https://github.com/ClickHouse/ClickHouse.git
synced 2024-11-21 23:21:59 +00:00
Merge branch 'master' into sentry-official-cpu-ram
This commit is contained in:
commit
97242e1fee
2
.gitmodules
vendored
2
.gitmodules
vendored
@ -157,7 +157,7 @@
|
||||
url = https://github.com/ClickHouse-Extras/libcpuid.git
|
||||
[submodule "contrib/openldap"]
|
||||
path = contrib/openldap
|
||||
url = https://github.com/openldap/openldap.git
|
||||
url = https://github.com/ClickHouse-Extras/openldap.git
|
||||
[submodule "contrib/AMQP-CPP"]
|
||||
path = contrib/AMQP-CPP
|
||||
url = https://github.com/ClickHouse-Extras/AMQP-CPP.git
|
||||
|
@ -14,3 +14,7 @@ ClickHouse® is an open-source column-oriented database management system that a
|
||||
* [Yandex.Messenger channel](https://yandex.ru/chat/#/join/20e380d9-c7be-4123-ab06-e95fb946975e) shares announcements and useful links in Russian.
|
||||
* [Contacts](https://clickhouse.tech/#contacts) can help to get your questions answered if there are any.
|
||||
* You can also [fill this form](https://clickhouse.tech/#meet) to meet Yandex ClickHouse team in person.
|
||||
|
||||
## Upcoming Events
|
||||
* [SF Bay Area ClickHouse December Meetup (online)](https://www.meetup.com/San-Francisco-Bay-Area-ClickHouse-Meetup/events/274498897/) on 2 December 2020.
|
||||
* [SF Bay Area ClickHouse January Virtual Office Hours (online)](https://www.meetup.com/San-Francisco-Bay-Area-ClickHouse-Meetup/events/274273549/) on 20 January 2020.
|
||||
|
@ -127,7 +127,7 @@ String LineReader::readLine(const String & first_prompt, const String & second_p
|
||||
}
|
||||
#endif
|
||||
|
||||
line += (line.empty() ? "" : " ") + input;
|
||||
line += (line.empty() ? "" : "\n") + input;
|
||||
|
||||
if (!need_next_line)
|
||||
break;
|
||||
|
2
contrib/AMQP-CPP
vendored
2
contrib/AMQP-CPP
vendored
@ -1 +1 @@
|
||||
Subproject commit d63e1f016582e9faaaf279aa24513087a07bc6e7
|
||||
Subproject commit 03781aaff0f10ef41f902b8cf865fe0067180c10
|
2
contrib/cassandra
vendored
2
contrib/cassandra
vendored
@ -1 +1 @@
|
||||
Subproject commit a49b4e0e2696a4b8ef286a5b9538d1cbe8490509
|
||||
Subproject commit d10187efb25b26da391def077edf3c6f2f3a23dd
|
2
contrib/librdkafka
vendored
2
contrib/librdkafka
vendored
@ -1 +1 @@
|
||||
Subproject commit 2090cbf56b715247ec2be7f768707a7ab1bf7ede
|
||||
Subproject commit 9902bc4fb18bb441fa55ca154b341cdda191e5d3
|
2
contrib/mariadb-connector-c
vendored
2
contrib/mariadb-connector-c
vendored
@ -1 +1 @@
|
||||
Subproject commit 1485b0de3eaa1508dfe49a5ba1e4aa2a71fd8335
|
||||
Subproject commit e05523ca7c1fb8d095b612a1b1cfe96e199ffb17
|
2
contrib/openldap
vendored
2
contrib/openldap
vendored
@ -1 +1 @@
|
||||
Subproject commit 34b9ba94b30319ed6389a4e001d057f7983fe363
|
||||
Subproject commit 0208811b6043ca06fda8631a5e473df1ec515ccb
|
2
contrib/poco
vendored
2
contrib/poco
vendored
@ -1 +1 @@
|
||||
Subproject commit f49c6ab8d3aa71828bd1b411485c21722e8c9d82
|
||||
Subproject commit f3d791f6568b99366d089b4479f76a515beb66d5
|
@ -23,6 +23,7 @@ toc_title: Adopters
|
||||
| <a href="https://www.bigo.sg/" class="favicon">BIGO</a> | Video | Computing Platform | — | — | [Blog Article, August 2020](https://www.programmersought.com/article/44544895251/) |
|
||||
| <a href="https://www.bloomberg.com/" class="favicon">Bloomberg</a> | Finance, Media | Monitoring | 102 servers | — | [Slides, May 2018](https://www.slideshare.net/Altinity/http-analytics-for-6m-requests-per-second-using-clickhouse-by-alexander-bocharov) |
|
||||
| <a href="https://bloxy.info" class="favicon">Bloxy</a> | Blockchain | Analytics | — | — | [Slides in Russian, August 2018](https://github.com/ClickHouse/clickhouse-presentations/blob/master/meetup17/4_bloxy.pptx) |
|
||||
| <a href="https://www.bytedance.com" class="favicon">Bytedance</a> | Social platforms | — | — | — | [The ClickHouse Meetup East, October 2020](https://www.youtube.com/watch?v=ckChUkC3Pns) |
|
||||
| <a href="https://cardsmobile.ru/" class="favicon">CardsMobile</a> | Finance | Analytics | — | — | [VC.ru](https://vc.ru/s/cardsmobile/143449-rukovoditel-gruppy-analiza-dannyh) |
|
||||
| <a href="https://carto.com/" class="favicon">CARTO</a> | Business Intelligence | Geo analytics | — | — | [Geospatial processing with ClickHouse](https://carto.com/blog/geospatial-processing-with-clickhouse/) |
|
||||
| <a href="http://public.web.cern.ch/public/" class="favicon">CERN</a> | Research | Experiment | — | — | [Press release, April 2012](https://www.yandex.com/company/press_center/press_releases/2012/2012-04-10/) |
|
||||
|
@ -2293,6 +2293,47 @@ Result:
|
||||
└─────────────────────────┴─────────┘
|
||||
```
|
||||
|
||||
## system_events_show_zero_values {#system_events_show_zero_values}
|
||||
|
||||
Allows to select zero-valued events from [`system.events`](../../operations/system-tables/events.md).
|
||||
|
||||
Some monitoring systems require passing all the metrics values to them for each checkpoint, even if the metric value is zero.
|
||||
|
||||
Possible values:
|
||||
|
||||
- 0 — Disabled.
|
||||
- 1 — Enabled.
|
||||
|
||||
Default value: `0`.
|
||||
|
||||
**Examples**
|
||||
|
||||
Query
|
||||
|
||||
```sql
|
||||
SELECT * FROM system.events WHERE event='QueryMemoryLimitExceeded';
|
||||
```
|
||||
|
||||
Result
|
||||
|
||||
```text
|
||||
Ok.
|
||||
```
|
||||
|
||||
Query
|
||||
```sql
|
||||
SET system_events_show_zero_values = 1;
|
||||
SELECT * FROM system.events WHERE event='QueryMemoryLimitExceeded';
|
||||
```
|
||||
|
||||
Result
|
||||
|
||||
```text
|
||||
┌─event────────────────────┬─value─┬─description───────────────────────────────────────────┐
|
||||
│ QueryMemoryLimitExceeded │ 0 │ Number of times when memory limit exceeded for query. │
|
||||
└──────────────────────────┴───────┴───────────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
## allow_experimental_bigint_types {#allow_experimental_bigint_types}
|
||||
|
||||
Enables or disables integer values exceeding the range that is supported by the int data type.
|
||||
|
@ -536,4 +536,58 @@ For case-insensitive search or/and in UTF-8 format use functions `ngramSearchCas
|
||||
!!! note "Note"
|
||||
For UTF-8 case we use 3-gram distance. All these are not perfectly fair n-gram distances. We use 2-byte hashes to hash n-grams and then calculate the (non-)symmetric difference between these hash tables – collisions may occur. With UTF-8 case-insensitive format we do not use fair `tolower` function – we zero the 5-th bit (starting from zero) of each codepoint byte and first bit of zeroth byte if bytes more than one – this works for Latin and mostly for all Cyrillic letters.
|
||||
|
||||
## countSubstrings(haystack, needle) {#countSubstrings}
|
||||
|
||||
Count the number of substring occurrences
|
||||
|
||||
For a case-insensitive search, use the function `countSubstringsCaseInsensitive` (or `countSubstringsCaseInsensitiveUTF8`).
|
||||
|
||||
**Syntax**
|
||||
|
||||
``` sql
|
||||
countSubstrings(haystack, needle[, start_pos])
|
||||
```
|
||||
|
||||
**Parameters**
|
||||
|
||||
- `haystack` — The string to search in. [String](../../sql-reference/syntax.md#syntax-string-literal).
|
||||
- `needle` — The substring to search for. [String](../../sql-reference/syntax.md#syntax-string-literal).
|
||||
- `start_pos` – Optional parameter, position of the first character in the string to start search. [UInt](../../sql-reference/data-types/int-uint.md)
|
||||
|
||||
**Returned values**
|
||||
|
||||
- Number of occurrences.
|
||||
|
||||
Type: `Integer`.
|
||||
|
||||
**Examples**
|
||||
|
||||
Query:
|
||||
|
||||
``` sql
|
||||
SELECT countSubstrings('foobar.com', '.')
|
||||
```
|
||||
|
||||
Result:
|
||||
|
||||
``` text
|
||||
┌─countSubstrings('foobar.com', '.')─┐
|
||||
│ 1 │
|
||||
└────────────────────────────────────┘
|
||||
```
|
||||
|
||||
Query:
|
||||
|
||||
``` sql
|
||||
SELECT countSubstrings('aaaa', 'aa')
|
||||
```
|
||||
|
||||
Result:
|
||||
|
||||
``` text
|
||||
┌─countSubstrings('aaaa', 'aa')─┐
|
||||
│ 2 │
|
||||
└───────────────────────────────┘
|
||||
```
|
||||
|
||||
[Original article](https://clickhouse.tech/docs/en/query_language/functions/string_search_functions/) <!--hide-->
|
||||
|
@ -2099,6 +2099,48 @@ SELECT TOP 3 name, value FROM system.settings;
|
||||
└─────────────────────────┴─────────┘
|
||||
```
|
||||
|
||||
## system_events_show_zero_values {#system_events_show_zero_values}
|
||||
|
||||
Позволяет выбрать события с нулевыми значениями из таблицы [`system.events`](../../operations/system-tables/events.md).
|
||||
|
||||
В некоторые системы мониторинга вам нужно передать значения всех измерений (для каждой контрольной точки), даже если в результате — "0".
|
||||
|
||||
Возможные значения:
|
||||
|
||||
- 0 — настройка отключена — вы получите все события.
|
||||
- 1 — настройка включена — вы сможете отсортировать события по нулевым и остальным значениям.
|
||||
|
||||
Значение по умолчанию: `0`.
|
||||
|
||||
**Примеры**
|
||||
|
||||
Запрос
|
||||
|
||||
```sql
|
||||
SELECT * FROM system.events WHERE event='QueryMemoryLimitExceeded';
|
||||
```
|
||||
|
||||
Результат
|
||||
|
||||
```text
|
||||
Ok.
|
||||
```
|
||||
|
||||
Запрос
|
||||
|
||||
```sql
|
||||
SET system_events_show_zero_values = 1;
|
||||
SELECT * FROM system.events WHERE event='QueryMemoryLimitExceeded';
|
||||
```
|
||||
|
||||
Результат
|
||||
|
||||
```text
|
||||
┌─event────────────────────┬─value─┬─description───────────────────────────────────────────┐
|
||||
│ QueryMemoryLimitExceeded │ 0 │ Number of times when memory limit exceeded for query. │
|
||||
└──────────────────────────┴───────┴───────────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
## allow_experimental_bigint_types {#allow_experimental_bigint_types}
|
||||
|
||||
Включает или отключает поддержку целочисленных значений, превышающих максимальное значение, допустимое для типа `int`.
|
||||
|
@ -79,11 +79,18 @@ namespace
|
||||
assert_cast<ColumnString &>(column).insert(value.convert<String>());
|
||||
break;
|
||||
case ValueType::vtDate:
|
||||
assert_cast<ColumnUInt16 &>(column).insertValue(UInt16{LocalDate{value.convert<String>()}.getDayNum()});
|
||||
{
|
||||
Poco::DateTime date = value.convert<Poco::DateTime>();
|
||||
assert_cast<ColumnUInt16 &>(column).insertValue(UInt16{LocalDate(date.year(), date.month(), date.day()).getDayNum()});
|
||||
break;
|
||||
}
|
||||
case ValueType::vtDateTime:
|
||||
assert_cast<ColumnUInt32 &>(column).insertValue(time_t{LocalDateTime{value.convert<String>()}});
|
||||
{
|
||||
Poco::DateTime datetime = value.convert<Poco::DateTime>();
|
||||
assert_cast<ColumnUInt32 &>(column).insertValue(time_t{LocalDateTime(
|
||||
datetime.year(), datetime.month(), datetime.day(), datetime.hour(), datetime.minute(), datetime.second())});
|
||||
break;
|
||||
}
|
||||
case ValueType::vtUUID:
|
||||
assert_cast<ColumnUInt128 &>(column).insert(parse<UUID>(value.convert<std::string>()));
|
||||
break;
|
||||
@ -112,6 +119,7 @@ Block ODBCBlockInputStream::readImpl()
|
||||
|
||||
for (const auto idx : ext::range(0, row.fieldCount()))
|
||||
{
|
||||
/// TODO This is extremely slow.
|
||||
const Poco::Dynamic::Var & value = row[idx];
|
||||
|
||||
if (!value.isEmpty())
|
||||
|
@ -358,6 +358,8 @@ DataTypePtr getLeastSupertype(const DataTypes & types)
|
||||
maximize(max_bits_of_unsigned_integer, 32);
|
||||
else if (typeid_cast<const DataTypeUInt64 *>(type.get()))
|
||||
maximize(max_bits_of_unsigned_integer, 64);
|
||||
else if (typeid_cast<const DataTypeUInt256 *>(type.get()))
|
||||
maximize(max_bits_of_unsigned_integer, 256);
|
||||
else if (typeid_cast<const DataTypeInt8 *>(type.get()))
|
||||
maximize(max_bits_of_signed_integer, 8);
|
||||
else if (typeid_cast<const DataTypeInt16 *>(type.get()))
|
||||
@ -366,6 +368,10 @@ DataTypePtr getLeastSupertype(const DataTypes & types)
|
||||
maximize(max_bits_of_signed_integer, 32);
|
||||
else if (typeid_cast<const DataTypeInt64 *>(type.get()))
|
||||
maximize(max_bits_of_signed_integer, 64);
|
||||
else if (typeid_cast<const DataTypeInt128 *>(type.get()))
|
||||
maximize(max_bits_of_signed_integer, 128);
|
||||
else if (typeid_cast<const DataTypeInt256 *>(type.get()))
|
||||
maximize(max_bits_of_signed_integer, 256);
|
||||
else if (typeid_cast<const DataTypeFloat32 *>(type.get()))
|
||||
maximize(max_mantissa_bits_of_floating, 24);
|
||||
else if (typeid_cast<const DataTypeFloat64 *>(type.get()))
|
||||
@ -386,7 +392,18 @@ DataTypePtr getLeastSupertype(const DataTypes & types)
|
||||
|
||||
/// If unsigned is not covered by signed.
|
||||
if (max_bits_of_signed_integer && max_bits_of_unsigned_integer >= max_bits_of_signed_integer)
|
||||
++min_bit_width_of_integer;
|
||||
{
|
||||
// Because 128 and 256 bit integers are significantly slower, we should not promote to them.
|
||||
// But if we already have wide numbers, promotion is necessary.
|
||||
if (min_bit_width_of_integer != 64)
|
||||
++min_bit_width_of_integer;
|
||||
else
|
||||
throw Exception(
|
||||
getExceptionMessagePrefix(types)
|
||||
+ " because some of them are signed integers and some are unsigned integers,"
|
||||
" but there is no signed integer type, that can exactly represent all required unsigned integer values",
|
||||
ErrorCodes::NO_COMMON_TYPE);
|
||||
}
|
||||
|
||||
/// If the result must be floating.
|
||||
if (max_mantissa_bits_of_floating)
|
||||
@ -413,6 +430,10 @@ DataTypePtr getLeastSupertype(const DataTypes & types)
|
||||
return std::make_shared<DataTypeInt32>();
|
||||
else if (min_bit_width_of_integer <= 64)
|
||||
return std::make_shared<DataTypeInt64>();
|
||||
else if (min_bit_width_of_integer <= 128)
|
||||
return std::make_shared<DataTypeInt128>();
|
||||
else if (min_bit_width_of_integer <= 256)
|
||||
return std::make_shared<DataTypeInt256>();
|
||||
else
|
||||
throw Exception(getExceptionMessagePrefix(types)
|
||||
+ " because some of them are signed integers and some are unsigned integers,"
|
||||
@ -429,6 +450,8 @@ DataTypePtr getLeastSupertype(const DataTypes & types)
|
||||
return std::make_shared<DataTypeUInt32>();
|
||||
else if (min_bit_width_of_integer <= 64)
|
||||
return std::make_shared<DataTypeUInt64>();
|
||||
else if (min_bit_width_of_integer <= 256)
|
||||
return std::make_shared<DataTypeUInt256>();
|
||||
else
|
||||
throw Exception("Logical error: " + getExceptionMessagePrefix(types)
|
||||
+ " but as all data types are unsigned integers, we must have found maximum unsigned integer type", ErrorCodes::NO_COMMON_TYPE);
|
||||
|
232
src/Functions/CountSubstringsImpl.h
Normal file
232
src/Functions/CountSubstringsImpl.h
Normal file
@ -0,0 +1,232 @@
|
||||
#pragma once
|
||||
|
||||
#include "PositionImpl.h"
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
namespace DB
|
||||
{
|
||||
|
||||
namespace ErrorCodes
|
||||
{
|
||||
extern const int ILLEGAL_COLUMN;
|
||||
}
|
||||
|
||||
|
||||
/// Implementation of the countSubstrings() using helpers for position()
|
||||
///
|
||||
/// NOTE: Intersecting substrings in haystack accounted only once, i.e.:
|
||||
///
|
||||
/// countSubstrings('aaaa', 'aa') == 2
|
||||
template <typename Impl>
|
||||
struct CountSubstringsImpl
|
||||
{
|
||||
static constexpr bool use_default_implementation_for_constants = false;
|
||||
static constexpr bool supports_start_pos = true;
|
||||
|
||||
using ResultType = UInt64;
|
||||
|
||||
/// Count occurrences of one substring in many strings.
|
||||
static void vectorConstant(
|
||||
const ColumnString::Chars & data,
|
||||
const ColumnString::Offsets & offsets,
|
||||
const std::string & needle,
|
||||
const ColumnPtr & start_pos,
|
||||
PaddedPODArray<UInt64> & res)
|
||||
{
|
||||
const UInt8 * begin = data.data();
|
||||
const UInt8 * pos = begin;
|
||||
const UInt8 * end = pos + data.size();
|
||||
|
||||
/// FIXME: suboptimal
|
||||
memset(&res[0], 0, res.size() * sizeof(res[0]));
|
||||
|
||||
/// Current index in the array of strings.
|
||||
size_t i = 0;
|
||||
|
||||
typename Impl::SearcherInBigHaystack searcher = Impl::createSearcherInBigHaystack(needle.data(), needle.size(), end - pos);
|
||||
|
||||
/// We will search for the next occurrence in all strings at once.
|
||||
while (pos < end && end != (pos = searcher.search(pos, end - pos)))
|
||||
{
|
||||
/// Determine which index it refers to.
|
||||
while (begin + offsets[i] <= pos)
|
||||
++i;
|
||||
|
||||
auto start = start_pos != nullptr ? start_pos->getUInt(i) : 0;
|
||||
|
||||
/// We check that the entry does not pass through the boundaries of strings.
|
||||
if (pos + needle.size() < begin + offsets[i])
|
||||
{
|
||||
auto res_pos = needle.size() + Impl::countChars(reinterpret_cast<const char *>(begin + offsets[i - 1]), reinterpret_cast<const char *>(pos));
|
||||
if (res_pos >= start)
|
||||
{
|
||||
++res[i];
|
||||
}
|
||||
/// Intersecting substrings in haystack accounted only once
|
||||
pos += needle.size();
|
||||
continue;
|
||||
}
|
||||
pos = begin + offsets[i];
|
||||
++i;
|
||||
}
|
||||
}
|
||||
|
||||
/// Count number of occurrences of substring in string.
|
||||
static void constantConstantScalar(
|
||||
std::string data,
|
||||
std::string needle,
|
||||
UInt64 start_pos,
|
||||
UInt64 & res)
|
||||
{
|
||||
res = 0;
|
||||
|
||||
if (needle.size() == 0)
|
||||
return;
|
||||
|
||||
auto start = std::max(start_pos, UInt64(1));
|
||||
size_t start_byte = Impl::advancePos(data.data(), data.data() + data.size(), start - 1) - data.data();
|
||||
size_t new_start_byte;
|
||||
while ((new_start_byte = data.find(needle, start_byte)) != std::string::npos)
|
||||
{
|
||||
++res;
|
||||
/// Intersecting substrings in haystack accounted only once
|
||||
start_byte = new_start_byte + needle.size();
|
||||
}
|
||||
}
|
||||
|
||||
/// Count number of occurrences of substring in string starting from different positions.
|
||||
static void constantConstant(
|
||||
std::string data,
|
||||
std::string needle,
|
||||
const ColumnPtr & start_pos,
|
||||
PaddedPODArray<UInt64> & res)
|
||||
{
|
||||
Impl::toLowerIfNeed(data);
|
||||
Impl::toLowerIfNeed(needle);
|
||||
|
||||
if (start_pos == nullptr)
|
||||
{
|
||||
constantConstantScalar(data, needle, 0, res[0]);
|
||||
return;
|
||||
}
|
||||
|
||||
size_t haystack_size = Impl::countChars(data.data(), data.data() + data.size());
|
||||
|
||||
size_t size = start_pos != nullptr ? start_pos->size() : 0;
|
||||
for (size_t i = 0; i < size; ++i)
|
||||
{
|
||||
auto start = start_pos->getUInt(i);
|
||||
|
||||
if (start > haystack_size + 1)
|
||||
{
|
||||
res[i] = 0;
|
||||
continue;
|
||||
}
|
||||
constantConstantScalar(data, needle, start, res[i]);
|
||||
}
|
||||
}
|
||||
|
||||
/// Count number of occurrences of substring each time for a different inside each time different string.
|
||||
static void vectorVector(
|
||||
const ColumnString::Chars & haystack_data,
|
||||
const ColumnString::Offsets & haystack_offsets,
|
||||
const ColumnString::Chars & needle_data,
|
||||
const ColumnString::Offsets & needle_offsets,
|
||||
const ColumnPtr & start_pos,
|
||||
PaddedPODArray<UInt64> & res)
|
||||
{
|
||||
ColumnString::Offset prev_haystack_offset = 0;
|
||||
ColumnString::Offset prev_needle_offset = 0;
|
||||
|
||||
size_t size = haystack_offsets.size();
|
||||
|
||||
for (size_t i = 0; i < size; ++i)
|
||||
{
|
||||
size_t needle_size = needle_offsets[i] - prev_needle_offset - 1;
|
||||
size_t haystack_size = haystack_offsets[i] - prev_haystack_offset - 1;
|
||||
|
||||
auto start = start_pos != nullptr ? std::max(start_pos->getUInt(i), UInt64(1)) : UInt64(1);
|
||||
|
||||
res[i] = 0;
|
||||
if (start > haystack_size + 1)
|
||||
{
|
||||
/// 0 already
|
||||
}
|
||||
else if (0 == needle_size)
|
||||
{
|
||||
/// 0 already
|
||||
}
|
||||
else
|
||||
{
|
||||
/// It is assumed that the StringSearcher is not very difficult to initialize.
|
||||
typename Impl::SearcherInSmallHaystack searcher = Impl::createSearcherInSmallHaystack(
|
||||
reinterpret_cast<const char *>(&needle_data[prev_needle_offset]),
|
||||
needle_offsets[i] - prev_needle_offset - 1); /// zero byte at the end
|
||||
|
||||
const UInt8 * end = reinterpret_cast<const UInt8 *>(&haystack_data[haystack_offsets[i] - 1]);
|
||||
const UInt8 * beg = reinterpret_cast<const UInt8 *>(Impl::advancePos(reinterpret_cast<const char *>(&haystack_data[prev_haystack_offset]), reinterpret_cast<const char *>(end), start - 1));
|
||||
|
||||
const UInt8 * pos;
|
||||
/// searcher returns a pointer to the found substring or to the end of `haystack`.
|
||||
while ((pos = searcher.search(beg, end)) < end)
|
||||
{
|
||||
++res[i];
|
||||
beg = pos + needle_size;
|
||||
}
|
||||
}
|
||||
|
||||
prev_haystack_offset = haystack_offsets[i];
|
||||
prev_needle_offset = needle_offsets[i];
|
||||
}
|
||||
}
|
||||
|
||||
/// Count number of substrings occurrences in the single string.
|
||||
static void constantVector(
|
||||
const String & haystack,
|
||||
const ColumnString::Chars & needle_data,
|
||||
const ColumnString::Offsets & needle_offsets,
|
||||
const ColumnPtr & start_pos,
|
||||
PaddedPODArray<UInt64> & res)
|
||||
{
|
||||
/// NOTE You could use haystack indexing. But this is a rare case.
|
||||
|
||||
ColumnString::Offset prev_needle_offset = 0;
|
||||
|
||||
size_t size = needle_offsets.size();
|
||||
|
||||
for (size_t i = 0; i < size; ++i)
|
||||
{
|
||||
res[i] = 0;
|
||||
auto start = start_pos != nullptr ? std::max(start_pos->getUInt(i), UInt64(1)) : UInt64(1);
|
||||
if (start <= haystack.size() + 1)
|
||||
{
|
||||
const char * needle_beg = reinterpret_cast<const char *>(&needle_data[prev_needle_offset]);
|
||||
size_t needle_size = needle_offsets[i] - prev_needle_offset - 1;
|
||||
|
||||
typename Impl::SearcherInSmallHaystack searcher = Impl::createSearcherInSmallHaystack(needle_beg, needle_size);
|
||||
|
||||
const UInt8 * end = reinterpret_cast<const UInt8 *>(haystack.data() + haystack.size());
|
||||
const UInt8 * beg = reinterpret_cast<const UInt8 *>(Impl::advancePos(haystack.data(), reinterpret_cast<const char *>(end), start - 1));
|
||||
|
||||
const UInt8 * pos;
|
||||
while ((pos = searcher.search(beg, end)) < end)
|
||||
{
|
||||
++res[i];
|
||||
beg = pos + needle_size;
|
||||
}
|
||||
}
|
||||
|
||||
prev_needle_offset = needle_offsets[i];
|
||||
}
|
||||
}
|
||||
|
||||
template <typename... Args>
|
||||
static void vectorFixedConstant(Args &&...)
|
||||
{
|
||||
throw Exception("Functions 'position' don't support FixedString haystack argument", ErrorCodes::ILLEGAL_COLUMN);
|
||||
}
|
||||
};
|
||||
|
||||
}
|
@ -117,7 +117,7 @@ struct ConvertImpl
|
||||
if (std::is_same_v<Name, NameToUnixTimestamp>)
|
||||
{
|
||||
if (isDate(named_from.type))
|
||||
throw Exception("Illegal column " + named_from.column->getName() + " of first argument of function " + Name::name,
|
||||
throw Exception("Illegal type " + named_from.type->getName() + " of first argument of function " + Name::name,
|
||||
ErrorCodes::ILLEGAL_COLUMN);
|
||||
}
|
||||
|
||||
|
@ -29,6 +29,9 @@ namespace DB
|
||||
* multiMatchAnyIndex(haystack, [pattern_1, pattern_2, ..., pattern_n]) -- search by re2 regular expressions pattern_i; Returns index of any match or zero if none;
|
||||
* multiMatchAllIndices(haystack, [pattern_1, pattern_2, ..., pattern_n]) -- search by re2 regular expressions pattern_i; Returns an array of matched indices in any order;
|
||||
*
|
||||
* countSubstrings(haystack, needle) -- count number of occurences of needle in haystack.
|
||||
* countSubstringsCaseInsensitive(haystack, needle)
|
||||
*
|
||||
* Applies regexp re2 and pulls:
|
||||
* - the first subpattern, if the regexp has a subpattern;
|
||||
* - the zero subpattern (the match part, otherwise);
|
||||
|
24
src/Functions/countSubstrings.cpp
Normal file
24
src/Functions/countSubstrings.cpp
Normal file
@ -0,0 +1,24 @@
|
||||
#include "FunctionsStringSearch.h"
|
||||
#include "FunctionFactory.h"
|
||||
#include "CountSubstringsImpl.h"
|
||||
|
||||
|
||||
namespace DB
|
||||
{
|
||||
namespace
|
||||
{
|
||||
|
||||
struct NameCountSubstrings
|
||||
{
|
||||
static constexpr auto name = "countSubstrings";
|
||||
};
|
||||
|
||||
using FunctionCountSubstrings = FunctionsStringSearch<CountSubstringsImpl<PositionCaseSensitiveASCII>, NameCountSubstrings>;
|
||||
|
||||
}
|
||||
|
||||
void registerFunctionCountSubstrings(FunctionFactory & factory)
|
||||
{
|
||||
factory.registerFunction<FunctionCountSubstrings>(FunctionFactory::CaseInsensitive);
|
||||
}
|
||||
}
|
24
src/Functions/countSubstringsCaseInsensitive.cpp
Normal file
24
src/Functions/countSubstringsCaseInsensitive.cpp
Normal file
@ -0,0 +1,24 @@
|
||||
#include "FunctionsStringSearch.h"
|
||||
#include "FunctionFactory.h"
|
||||
#include "CountSubstringsImpl.h"
|
||||
|
||||
|
||||
namespace DB
|
||||
{
|
||||
namespace
|
||||
{
|
||||
|
||||
struct NameCountSubstringsCaseInsensitive
|
||||
{
|
||||
static constexpr auto name = "countSubstringsCaseInsensitive";
|
||||
};
|
||||
|
||||
using FunctionCountSubstringsCaseInsensitive = FunctionsStringSearch<CountSubstringsImpl<PositionCaseInsensitiveASCII>, NameCountSubstringsCaseInsensitive>;
|
||||
|
||||
}
|
||||
|
||||
void registerFunctionCountSubstringsCaseInsensitive(FunctionFactory & factory)
|
||||
{
|
||||
factory.registerFunction<FunctionCountSubstringsCaseInsensitive>();
|
||||
}
|
||||
}
|
24
src/Functions/countSubstringsCaseInsensitiveUTF8.cpp
Normal file
24
src/Functions/countSubstringsCaseInsensitiveUTF8.cpp
Normal file
@ -0,0 +1,24 @@
|
||||
#include "FunctionsStringSearch.h"
|
||||
#include "FunctionFactory.h"
|
||||
#include "CountSubstringsImpl.h"
|
||||
|
||||
|
||||
namespace DB
|
||||
{
|
||||
namespace
|
||||
{
|
||||
|
||||
struct NameCountSubstringsCaseInsensitiveUTF8
|
||||
{
|
||||
static constexpr auto name = "countSubstringsCaseInsensitiveUTF8";
|
||||
};
|
||||
|
||||
using FunctionCountSubstringsCaseInsensitiveUTF8 = FunctionsStringSearch<CountSubstringsImpl<PositionCaseInsensitiveUTF8>, NameCountSubstringsCaseInsensitiveUTF8>;
|
||||
|
||||
}
|
||||
|
||||
void registerFunctionCountSubstringsCaseInsensitiveUTF8(FunctionFactory & factory)
|
||||
{
|
||||
factory.registerFunction<FunctionCountSubstringsCaseInsensitiveUTF8>();
|
||||
}
|
||||
}
|
@ -31,6 +31,10 @@ void registerFunctionMultiSearchAllPositionsCaseInsensitiveUTF8(FunctionFactory
|
||||
void registerFunctionHasToken(FunctionFactory &);
|
||||
void registerFunctionHasTokenCaseInsensitive(FunctionFactory &);
|
||||
|
||||
void registerFunctionCountSubstrings(FunctionFactory &);
|
||||
void registerFunctionCountSubstringsCaseInsensitive(FunctionFactory &);
|
||||
void registerFunctionCountSubstringsCaseInsensitiveUTF8(FunctionFactory &);
|
||||
|
||||
|
||||
void registerFunctionsStringSearch(FunctionFactory & factory)
|
||||
{
|
||||
@ -61,6 +65,10 @@ void registerFunctionsStringSearch(FunctionFactory & factory)
|
||||
|
||||
registerFunctionHasToken(factory);
|
||||
registerFunctionHasTokenCaseInsensitive(factory);
|
||||
|
||||
registerFunctionCountSubstrings(factory);
|
||||
registerFunctionCountSubstringsCaseInsensitive(factory);
|
||||
registerFunctionCountSubstringsCaseInsensitiveUTF8(factory);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -208,6 +208,9 @@ SRCS(
|
||||
cos.cpp
|
||||
cosh.cpp
|
||||
countDigits.cpp
|
||||
countSubstrings.cpp
|
||||
countSubstringsCaseInsensitive.cpp
|
||||
countSubstringsCaseInsensitiveUTF8.cpp
|
||||
currentDatabase.cpp
|
||||
currentUser.cpp
|
||||
dateDiff.cpp
|
||||
|
@ -20,8 +20,8 @@ struct KeepAggregateFunctionMatcher
|
||||
{
|
||||
struct Data
|
||||
{
|
||||
std::unordered_set<String> & group_by_keys;
|
||||
bool & keep_aggregator;
|
||||
const NameSet & group_by_keys;
|
||||
bool keep_aggregator;
|
||||
};
|
||||
|
||||
using Visitor = InDepthNodeVisitor<KeepAggregateFunctionMatcher, true>;
|
||||
@ -33,7 +33,7 @@ struct KeepAggregateFunctionMatcher
|
||||
|
||||
static void visit(ASTFunction & function_node, Data & data)
|
||||
{
|
||||
if ((function_node.arguments->children).empty())
|
||||
if (function_node.arguments->children.empty())
|
||||
{
|
||||
data.keep_aggregator = true;
|
||||
return;
|
||||
@ -47,12 +47,9 @@ struct KeepAggregateFunctionMatcher
|
||||
|
||||
static void visit(ASTIdentifier & ident, Data & data)
|
||||
{
|
||||
if (!data.group_by_keys.count(ident.shortName()))
|
||||
{
|
||||
/// if variable of a function is not in GROUP BY keys, this function should not be deleted
|
||||
/// if variable of a function is not in GROUP BY keys, this function should not be deleted
|
||||
if (!data.group_by_keys.count(ident.getColumnName()))
|
||||
data.keep_aggregator = true;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
static void visit(const ASTPtr & ast, Data & data)
|
||||
@ -75,21 +72,21 @@ struct KeepAggregateFunctionMatcher
|
||||
}
|
||||
};
|
||||
|
||||
using KeepAggregateFunctionVisitor = InDepthNodeVisitor<KeepAggregateFunctionMatcher, true>;
|
||||
using KeepAggregateFunctionVisitor = KeepAggregateFunctionMatcher::Visitor;
|
||||
|
||||
class SelectAggregateFunctionOfGroupByKeysMatcher
|
||||
{
|
||||
public:
|
||||
struct Data
|
||||
{
|
||||
std::unordered_set<String> & group_by_keys;
|
||||
const NameSet & group_by_keys;
|
||||
};
|
||||
|
||||
static bool needChildVisit(const ASTPtr & node, const ASTPtr &)
|
||||
{
|
||||
/// Don't descent into table functions and subqueries and special case for ArrayJoin.
|
||||
return !node->as<ASTSubquery>() &&
|
||||
!(node->as<ASTTableExpression>() || node->as<ASTSelectWithUnionQuery>() || node->as<ASTArrayJoin>());
|
||||
return !node->as<ASTSubquery>() && !node->as<ASTTableExpression>()
|
||||
&& !node->as<ASTSelectWithUnionQuery>() && !node->as<ASTArrayJoin>();
|
||||
}
|
||||
|
||||
static void visit(ASTPtr & ast, Data & data)
|
||||
@ -99,12 +96,11 @@ public:
|
||||
if (function_node && (function_node->name == "min" || function_node->name == "max" ||
|
||||
function_node->name == "any" || function_node->name == "anyLast"))
|
||||
{
|
||||
bool keep_aggregator = false;
|
||||
KeepAggregateFunctionVisitor::Data keep_data{data.group_by_keys, keep_aggregator};
|
||||
KeepAggregateFunctionVisitor::Data keep_data{data.group_by_keys, false};
|
||||
KeepAggregateFunctionVisitor(keep_data).visit(function_node->arguments);
|
||||
|
||||
/// Place argument of an aggregate function instead of function
|
||||
if (!keep_aggregator && !function_node->arguments->children.empty())
|
||||
if (!keep_data.keep_aggregator && !function_node->arguments->children.empty())
|
||||
{
|
||||
String alias = function_node->alias;
|
||||
ast = (function_node->arguments->children[0])->clone();
|
||||
|
@ -139,11 +139,6 @@ ExpressionAnalyzer::ExpressionAnalyzer(
|
||||
analyzeAggregation();
|
||||
}
|
||||
|
||||
bool ExpressionAnalyzer::isRemoteStorage() const
|
||||
{
|
||||
return storage() && storage()->isRemote();
|
||||
}
|
||||
|
||||
|
||||
void ExpressionAnalyzer::analyzeAggregation()
|
||||
{
|
||||
|
@ -164,7 +164,7 @@ protected:
|
||||
|
||||
const ASTSelectQuery * getSelectQuery() const;
|
||||
|
||||
bool isRemoteStorage() const;
|
||||
bool isRemoteStorage() const { return syntax->is_remote_storage; }
|
||||
};
|
||||
|
||||
class SelectQueryExpressionAnalyzer;
|
||||
|
@ -26,6 +26,7 @@
|
||||
#include <Parsers/ASTTablesInSelectQuery.h>
|
||||
|
||||
#include <Functions/FunctionFactory.h>
|
||||
#include <Storages/StorageInMemoryMetadata.h>
|
||||
|
||||
|
||||
namespace DB
|
||||
@ -177,43 +178,21 @@ void optimizeGroupBy(ASTSelectQuery * select_query, const NameSet & source_colum
|
||||
|
||||
struct GroupByKeysInfo
|
||||
{
|
||||
std::unordered_set<String> key_names; ///set of keys' short names
|
||||
bool has_identifier = false;
|
||||
NameSet key_names; ///set of keys' short names
|
||||
bool has_function = false;
|
||||
bool has_possible_collision = false;
|
||||
};
|
||||
|
||||
GroupByKeysInfo getGroupByKeysInfo(ASTs & group_keys)
|
||||
GroupByKeysInfo getGroupByKeysInfo(const ASTs & group_by_keys)
|
||||
{
|
||||
GroupByKeysInfo data;
|
||||
|
||||
///filling set with short names of keys
|
||||
for (auto & group_key : group_keys)
|
||||
/// filling set with short names of keys
|
||||
for (const auto & group_key : group_by_keys)
|
||||
{
|
||||
if (group_key->as<ASTFunction>())
|
||||
data.has_function = true;
|
||||
|
||||
if (auto * group_key_ident = group_key->as<ASTIdentifier>())
|
||||
{
|
||||
data.has_identifier = true;
|
||||
if (data.key_names.count(group_key_ident->shortName()))
|
||||
{
|
||||
///There may be a collision between different tables having similar variables.
|
||||
///Due to the fact that we can't track these conflicts yet,
|
||||
///it's better to disable some optimizations to avoid elimination necessary keys.
|
||||
data.has_possible_collision = true;
|
||||
}
|
||||
|
||||
data.key_names.insert(group_key_ident->shortName());
|
||||
}
|
||||
else if (auto * group_key_func = group_key->as<ASTFunction>())
|
||||
{
|
||||
data.key_names.insert(group_key_func->getColumnName());
|
||||
}
|
||||
else
|
||||
{
|
||||
data.key_names.insert(group_key->getColumnName());
|
||||
}
|
||||
data.key_names.insert(group_key->getColumnName());
|
||||
}
|
||||
|
||||
return data;
|
||||
@ -225,47 +204,28 @@ void optimizeGroupByFunctionKeys(ASTSelectQuery * select_query)
|
||||
if (!select_query->groupBy())
|
||||
return;
|
||||
|
||||
auto grp_by = select_query->groupBy();
|
||||
auto & group_keys = grp_by->children;
|
||||
auto group_by = select_query->groupBy();
|
||||
const auto & group_by_keys = group_by->children;
|
||||
|
||||
ASTs modified; ///result
|
||||
|
||||
GroupByKeysInfo group_by_keys_data = getGroupByKeysInfo(group_keys);
|
||||
GroupByKeysInfo group_by_keys_data = getGroupByKeysInfo(group_by_keys);
|
||||
|
||||
if (!group_by_keys_data.has_function || group_by_keys_data.has_possible_collision)
|
||||
if (!group_by_keys_data.has_function)
|
||||
return;
|
||||
|
||||
GroupByFunctionKeysVisitor::Data visitor_data{group_by_keys_data.key_names};
|
||||
GroupByFunctionKeysVisitor(visitor_data).visit(grp_by);
|
||||
GroupByFunctionKeysVisitor(visitor_data).visit(group_by);
|
||||
|
||||
modified.reserve(group_keys.size());
|
||||
modified.reserve(group_by_keys.size());
|
||||
|
||||
///filling the result
|
||||
for (auto & group_key : group_keys)
|
||||
{
|
||||
if (auto * group_key_func = group_key->as<ASTFunction>())
|
||||
{
|
||||
if (group_by_keys_data.key_names.count(group_key_func->getColumnName()))
|
||||
modified.push_back(group_key);
|
||||
/// filling the result
|
||||
for (const auto & group_key : group_by_keys)
|
||||
if (group_by_keys_data.key_names.count(group_key->getColumnName()))
|
||||
modified.push_back(group_key);
|
||||
|
||||
continue;
|
||||
}
|
||||
if (auto * group_key_ident = group_key->as<ASTIdentifier>())
|
||||
{
|
||||
if (group_by_keys_data.key_names.count(group_key_ident->shortName()))
|
||||
modified.push_back(group_key);
|
||||
|
||||
continue;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (group_by_keys_data.key_names.count(group_key->getColumnName()))
|
||||
modified.push_back(group_key);
|
||||
}
|
||||
}
|
||||
|
||||
///modifying the input
|
||||
grp_by->children = modified;
|
||||
/// modifying the input
|
||||
group_by->children = modified;
|
||||
}
|
||||
|
||||
/// Eliminates min/max/any-aggregators of functions of GROUP BY keys
|
||||
@ -274,10 +234,8 @@ void optimizeAggregateFunctionsOfGroupByKeys(ASTSelectQuery * select_query, ASTP
|
||||
if (!select_query->groupBy())
|
||||
return;
|
||||
|
||||
auto grp_by = select_query->groupBy();
|
||||
auto & group_keys = grp_by->children;
|
||||
|
||||
GroupByKeysInfo group_by_keys_data = getGroupByKeysInfo(group_keys);
|
||||
const auto & group_by_keys = select_query->groupBy()->children;
|
||||
GroupByKeysInfo group_by_keys_data = getGroupByKeysInfo(group_by_keys);
|
||||
|
||||
SelectAggregateFunctionOfGroupByKeysVisitor::Data visitor_data{group_by_keys_data.key_names};
|
||||
SelectAggregateFunctionOfGroupByKeysVisitor(visitor_data).visit(node);
|
||||
@ -438,7 +396,8 @@ void optimizeDuplicateDistinct(ASTSelectQuery & select)
|
||||
/// Replace monotonous functions in ORDER BY if they don't participate in GROUP BY expression,
|
||||
/// has a single argument and not an aggregate functions.
|
||||
void optimizeMonotonousFunctionsInOrderBy(ASTSelectQuery * select_query, const Context & context,
|
||||
const TablesWithColumns & tables_with_columns)
|
||||
const TablesWithColumns & tables_with_columns,
|
||||
const Names & sorting_key_columns)
|
||||
{
|
||||
auto order_by = select_query->orderBy();
|
||||
if (!order_by)
|
||||
@ -455,13 +414,22 @@ void optimizeMonotonousFunctionsInOrderBy(ASTSelectQuery * select_query, const C
|
||||
}
|
||||
}
|
||||
|
||||
for (auto & child : order_by->children)
|
||||
bool is_sorting_key_prefix = true;
|
||||
for (size_t i = 0; i < order_by->children.size(); ++i)
|
||||
{
|
||||
auto * order_by_element = child->as<ASTOrderByElement>();
|
||||
auto * order_by_element = order_by->children[i]->as<ASTOrderByElement>();
|
||||
auto & ast_func = order_by_element->children[0];
|
||||
if (!ast_func->as<ASTFunction>())
|
||||
continue;
|
||||
|
||||
if (i >= sorting_key_columns.size() || ast_func->getColumnName() != sorting_key_columns[i])
|
||||
is_sorting_key_prefix = false;
|
||||
|
||||
/// If order by expression matches the sorting key, do not remove
|
||||
/// functions to allow execute reading in order of key.
|
||||
if (is_sorting_key_prefix)
|
||||
continue;
|
||||
|
||||
MonotonicityCheckVisitor::Data data{tables_with_columns, context, group_by_hashes};
|
||||
MonotonicityCheckVisitor(data).visit(ast_func);
|
||||
|
||||
@ -611,7 +579,8 @@ void TreeOptimizer::optimizeIf(ASTPtr & query, Aliases & aliases, bool if_chain_
|
||||
|
||||
void TreeOptimizer::apply(ASTPtr & query, Aliases & aliases, const NameSet & source_columns_set,
|
||||
const std::vector<TableWithColumnNamesAndTypes> & tables_with_columns,
|
||||
const Context & context, bool & rewrite_subqueries)
|
||||
const Context & context, const StorageMetadataPtr & metadata_snapshot,
|
||||
bool & rewrite_subqueries)
|
||||
{
|
||||
const auto & settings = context.getSettingsRef();
|
||||
|
||||
@ -652,9 +621,6 @@ void TreeOptimizer::apply(ASTPtr & query, Aliases & aliases, const NameSet & sou
|
||||
optimizeAggregateFunctionsOfGroupByKeys(select_query, query);
|
||||
}
|
||||
|
||||
/// Remove duplicate items from ORDER BY.
|
||||
optimizeDuplicatesInOrderBy(select_query);
|
||||
|
||||
/// Remove duplicate ORDER BY and DISTINCT from subqueries.
|
||||
if (settings.optimize_duplicate_order_by_and_distinct)
|
||||
{
|
||||
@ -672,7 +638,13 @@ void TreeOptimizer::apply(ASTPtr & query, Aliases & aliases, const NameSet & sou
|
||||
|
||||
/// Replace monotonous functions with its argument
|
||||
if (settings.optimize_monotonous_functions_in_order_by)
|
||||
optimizeMonotonousFunctionsInOrderBy(select_query, context, tables_with_columns);
|
||||
optimizeMonotonousFunctionsInOrderBy(select_query, context, tables_with_columns,
|
||||
metadata_snapshot ? metadata_snapshot->getSortingKeyColumns() : Names{});
|
||||
|
||||
/// Remove duplicate items from ORDER BY.
|
||||
/// Execute it after all order by optimizations,
|
||||
/// because they can produce duplicated columns.
|
||||
optimizeDuplicatesInOrderBy(select_query);
|
||||
|
||||
/// If function "if" has String-type arguments, transform them into enum
|
||||
if (settings.optimize_if_transform_strings_to_enum)
|
||||
|
@ -8,6 +8,8 @@ namespace DB
|
||||
{
|
||||
|
||||
class Context;
|
||||
struct StorageInMemoryMetadata;
|
||||
using StorageMetadataPtr = std::shared_ptr<const StorageInMemoryMetadata>;
|
||||
|
||||
/// Part of of Tree Rewriter (SyntaxAnalyzer) that optimizes AST.
|
||||
/// Query should be ready to execute either before either after it. But resulting query could be faster.
|
||||
@ -16,7 +18,8 @@ class TreeOptimizer
|
||||
public:
|
||||
static void apply(ASTPtr & query, Aliases & aliases, const NameSet & source_columns_set,
|
||||
const std::vector<TableWithColumnNamesAndTypes> & tables_with_columns,
|
||||
const Context & context, bool & rewrite_subqueries);
|
||||
const Context & context, const StorageMetadataPtr & metadata_snapshot,
|
||||
bool & rewrite_subqueries);
|
||||
|
||||
static void optimizeIf(ASTPtr & query, Aliases & aliases, bool if_chain_to_multiif);
|
||||
};
|
||||
|
@ -387,6 +387,19 @@ std::vector<const ASTFunction *> getAggregates(ASTPtr & query, const ASTSelectQu
|
||||
|
||||
}
|
||||
|
||||
TreeRewriterResult::TreeRewriterResult(
|
||||
const NamesAndTypesList & source_columns_,
|
||||
ConstStoragePtr storage_,
|
||||
const StorageMetadataPtr & metadata_snapshot_,
|
||||
bool add_special)
|
||||
: storage(storage_)
|
||||
, metadata_snapshot(metadata_snapshot_)
|
||||
, source_columns(source_columns_)
|
||||
{
|
||||
collectSourceColumns(add_special);
|
||||
is_remote_storage = storage && storage->isRemote();
|
||||
}
|
||||
|
||||
/// Add columns from storage to source_columns list. Deduplicate resulted list.
|
||||
/// Special columns are non physical columns, for example ALIAS
|
||||
void TreeRewriterResult::collectSourceColumns(bool add_special)
|
||||
@ -645,7 +658,7 @@ TreeRewriterResultPtr TreeRewriter::analyzeSelect(
|
||||
/// Executing scalar subqueries - replacing them with constant values.
|
||||
executeScalarSubqueries(query, context, subquery_depth, result.scalars, select_options.only_analyze);
|
||||
|
||||
TreeOptimizer::apply(query, result.aliases, source_columns_set, tables_with_columns, context, result.rewrite_subqueries);
|
||||
TreeOptimizer::apply(query, result.aliases, source_columns_set, tables_with_columns, context, result.metadata_snapshot, result.rewrite_subqueries);
|
||||
|
||||
/// array_join_alias_to_name, array_join_result_to_source.
|
||||
getArrayJoinedColumns(query, result, select_query, result.source_columns, source_columns_set);
|
||||
|
@ -53,6 +53,9 @@ struct TreeRewriterResult
|
||||
|
||||
bool optimize_trivial_count = false;
|
||||
|
||||
/// Cache isRemote() call for storage, because it may be too heavy.
|
||||
bool is_remote_storage = false;
|
||||
|
||||
/// Results of scalar sub queries
|
||||
Scalars scalars;
|
||||
|
||||
@ -60,13 +63,7 @@ struct TreeRewriterResult
|
||||
const NamesAndTypesList & source_columns_,
|
||||
ConstStoragePtr storage_ = {},
|
||||
const StorageMetadataPtr & metadata_snapshot_ = {},
|
||||
bool add_special = true)
|
||||
: storage(storage_)
|
||||
, metadata_snapshot(metadata_snapshot_)
|
||||
, source_columns(source_columns_)
|
||||
{
|
||||
collectSourceColumns(add_special);
|
||||
}
|
||||
bool add_special = true);
|
||||
|
||||
void collectSourceColumns(bool add_special);
|
||||
void collectUsedColumns(const ASTPtr & query, bool is_select);
|
||||
|
@ -10,21 +10,18 @@ class ASTAssignment : public IAST
|
||||
{
|
||||
public:
|
||||
String column_name;
|
||||
ASTPtr expression;
|
||||
|
||||
ASTPtr expression() const
|
||||
{
|
||||
return children.at(0);
|
||||
}
|
||||
|
||||
String getID(char delim) const override { return "Assignment" + (delim + column_name); }
|
||||
|
||||
ASTPtr clone() const override
|
||||
{
|
||||
auto res = std::make_shared<ASTAssignment>(*this);
|
||||
res->children.clear();
|
||||
|
||||
if (expression)
|
||||
{
|
||||
res->expression = expression->clone();
|
||||
res->children.push_back(res->expression);
|
||||
}
|
||||
|
||||
res->children = { expression()->clone() };
|
||||
return res;
|
||||
}
|
||||
|
||||
@ -37,7 +34,7 @@ protected:
|
||||
|
||||
settings.ostr << (settings.hilite ? hilite_operator : "") << " = " << (settings.hilite ? hilite_none : "");
|
||||
|
||||
expression->formatImpl(settings, state, frame);
|
||||
expression()->formatImpl(settings, state, frame);
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -588,7 +588,6 @@ bool ParserAlterCommand::parseImpl(Pos & pos, ASTPtr & node, Expected & expected
|
||||
}
|
||||
else
|
||||
return false;
|
||||
|
||||
}
|
||||
|
||||
if (command->col_decl)
|
||||
@ -601,6 +600,14 @@ bool ParserAlterCommand::parseImpl(Pos & pos, ASTPtr & node, Expected & expected
|
||||
command->children.push_back(command->order_by);
|
||||
if (command->sample_by)
|
||||
command->children.push_back(command->sample_by);
|
||||
if (command->index_decl)
|
||||
command->children.push_back(command->index_decl);
|
||||
if (command->index)
|
||||
command->children.push_back(command->index);
|
||||
if (command->constraint_decl)
|
||||
command->children.push_back(command->constraint_decl);
|
||||
if (command->constraint)
|
||||
command->children.push_back(command->constraint);
|
||||
if (command->predicate)
|
||||
command->children.push_back(command->predicate);
|
||||
if (command->update_assignments)
|
||||
@ -613,6 +620,10 @@ bool ParserAlterCommand::parseImpl(Pos & pos, ASTPtr & node, Expected & expected
|
||||
command->children.push_back(command->ttl);
|
||||
if (command->settings_changes)
|
||||
command->children.push_back(command->settings_changes);
|
||||
if (command->select)
|
||||
command->children.push_back(command->select);
|
||||
if (command->rename_to)
|
||||
command->children.push_back(command->rename_to);
|
||||
|
||||
return true;
|
||||
}
|
||||
@ -656,12 +667,13 @@ bool ParserAssignment::parseImpl(Pos & pos, ASTPtr & node, Expected & expected)
|
||||
if (!s_equals.ignore(pos, expected))
|
||||
return false;
|
||||
|
||||
if (!p_expression.parse(pos, assignment->expression, expected))
|
||||
ASTPtr expression;
|
||||
if (!p_expression.parse(pos, expression, expected))
|
||||
return false;
|
||||
|
||||
tryGetIdentifierNameInto(column, assignment->column_name);
|
||||
if (assignment->expression)
|
||||
assignment->children.push_back(assignment->expression);
|
||||
if (expression)
|
||||
assignment->children.push_back(expression);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -62,7 +62,7 @@ std::initializer_list<std::string_view> nouns
|
||||
"affinity", "afoul", "afterlife", "aftermath", "afternoon", "aftershave", "aftershock", "afterthought", "age", "agency", "agenda", "agent",
|
||||
"aggradation", "aggression", "aglet", "agony", "agreement", "agriculture", "aid", "aide", "aim", "air", "airbag", "airbus", "aircraft",
|
||||
"airfare", "airfield", "airforce", "airline", "airmail", "airman", "airplane", "airport", "airship", "airspace", "alarm", "alb", "albatross",
|
||||
"album", "alcohol", "alcove", "alder", "ale", "alert", "alfalfa", "algebra", "algorithm", "alias", "alibi", "alien", "allegation", "allergist",
|
||||
"album", "alcohol", "alcove", "alder", "ale", "alert", "alfalfa", "algebra", "algorithm", "alibi", "alien", "allegation", "allergist",
|
||||
"alley", "alliance", "alligator", "allocation", "allowance", "alloy", "alluvium", "almanac", "almighty", "almond", "alpaca", "alpenglow",
|
||||
"alpenhorn", "alpha", "alphabet", "altar", "alteration", "alternative", "altitude", "alto", "aluminium", "aluminum", "amazement", "amazon",
|
||||
"ambassador", "amber", "ambience", "ambiguity", "ambition", "ambulance", "amendment", "amenity", "ammunition", "amnesty", "amount", "amusement",
|
||||
@ -124,7 +124,7 @@ std::initializer_list<std::string_view> nouns
|
||||
"captain", "caption", "captor", "car", "carabao", "caramel", "caravan", "carbohydrate", "carbon", "carboxyl", "card", "cardboard", "cardigan",
|
||||
"care", "career", "cargo", "caribou", "carload", "carnation", "carnival", "carol", "carotene", "carp", "carpenter", "carpet", "carpeting",
|
||||
"carport", "carriage", "carrier", "carrot", "carry", "cart", "cartel", "carter", "cartilage", "cartload", "cartoon", "cartridge", "carving",
|
||||
"cascade", "case", "casement", "cash", "cashew", "cashier", "casino", "casket", "cassava", "casserole", "cassock", "cast", "castanet",
|
||||
"cascade", "casement", "cash", "cashew", "cashier", "casino", "casket", "cassava", "casserole", "cassock", "cast", "castanet",
|
||||
"castle", "casualty", "cat", "catacomb", "catalogue", "catalysis", "catalyst", "catamaran", "catastrophe", "catch", "catcher", "category",
|
||||
"caterpillar", "cathedral", "cation", "catsup", "cattle", "cauliflower", "causal", "cause", "causeway", "caution", "cave", "caviar",
|
||||
"cayenne", "ceiling", "celebration", "celebrity", "celeriac", "celery", "cell", "cellar", "cello", "celsius", "cement", "cemetery", "cenotaph",
|
||||
@ -184,10 +184,10 @@ std::initializer_list<std::string_view> nouns
|
||||
"cut", "cuticle", "cutlet", "cutover", "cutting", "cyclamen", "cycle", "cyclone", "cyclooxygenase", "cygnet", "cylinder", "cymbal", "cynic",
|
||||
"cyst", "cytokine", "cytoplasm", "dad", "daddy", "daffodil", "dagger", "dahlia", "daikon", "daily", "dairy", "daisy", "dam", "damage",
|
||||
"dame", "dance", "dancer", "dancing", "dandelion", "danger", "dare", "dark", "darkness", "darn", "dart", "dash", "dashboard",
|
||||
"data", "database", "date", "daughter", "dawn", "day", "daybed", "daylight", "dead", "deadline", "deal", "dealer", "dealing", "dearest",
|
||||
"data", "date", "daughter", "dawn", "day", "daybed", "daylight", "dead", "deadline", "deal", "dealer", "dealing", "dearest",
|
||||
"death", "deathwatch", "debate", "debris", "debt", "debtor", "decade", "decadence", "decency", "decimal", "decision",
|
||||
"deck", "declaration", "declination", "decline", "decoder", "decongestant", "decoration", "decrease", "decryption", "dedication", "deduce",
|
||||
"deduction", "deed", "deep", "deer", "default", "defeat", "defendant", "defender", "defense", "deficit", "definition", "deformation",
|
||||
"deduction", "deed", "deep", "deer", "defeat", "defendant", "defender", "defense", "deficit", "definition", "deformation",
|
||||
"degradation", "degree", "delay", "deliberation", "delight", "delivery", "demand", "democracy", "democrat", "demon", "demur", "den",
|
||||
"denim", "denominator", "density", "dentist", "deodorant", "department", "departure", "dependency", "dependent", "deployment", "deposit",
|
||||
"deposition", "depot", "depression", "depressive", "depth", "deputy", "derby", "derivation", "derivative", "derrick", "descendant", "descent",
|
||||
@ -250,7 +250,7 @@ std::initializer_list<std::string_view> nouns
|
||||
"flytrap", "foal", "foam", "fob", "focus", "fog", "fold", "folder", "folk", "folklore", "follower", "following", "fondue", "font", "food",
|
||||
"foodstuffs", "fool", "foot", "footage", "football", "footnote", "footprint", "footrest", "footstep", "footstool", "footwear", "forage",
|
||||
"forager", "foray", "force", "ford", "forearm", "forebear", "forecast", "forehead", "foreigner", "forelimb", "forest", "forestry", "forever",
|
||||
"forgery", "fork", "form", "formal", "formamide", "format", "formation", "former", "formicarium", "formula", "fort", "forte", "fortnight",
|
||||
"forgery", "fork", "form", "formal", "formamide", "formation", "former", "formicarium", "formula", "fort", "forte", "fortnight",
|
||||
"fortress", "fortune", "forum", "foundation", "founder", "founding", "fountain", "fourths", "fowl", "fox", "foxglove", "fraction", "fragrance",
|
||||
"frame", "framework", "fratricide", "fraud", "fraudster", "freak", "freckle", "freedom", "freelance", "freezer", "freezing", "freight",
|
||||
"freighter", "frenzy", "freon", "frequency", "fresco", "friction", "fridge", "friend", "friendship", "fries", "frigate", "fright", "fringe",
|
||||
@ -271,7 +271,7 @@ std::initializer_list<std::string_view> nouns
|
||||
"grandfather", "grandma", "grandmom", "grandmother", "grandpa", "grandparent", "grandson", "granny", "granola", "grant", "grape", "grapefruit",
|
||||
"graph", "graphic", "grasp", "grass", "grasshopper", "grassland", "gratitude", "gravel", "gravitas", "gravity", "gravy", "gray", "grease",
|
||||
"greatness", "greed", "green", "greenhouse", "greens", "grenade", "grey", "grid", "grief",
|
||||
"grill", "grin", "grip", "gripper", "grit", "grocery", "ground", "group", "grouper", "grouse", "grove", "growth", "grub", "guacamole",
|
||||
"grill", "grin", "grip", "gripper", "grit", "grocery", "ground", "grouper", "grouse", "grove", "growth", "grub", "guacamole",
|
||||
"guarantee", "guard", "guava", "guerrilla", "guess", "guest", "guestbook", "guidance", "guide", "guideline", "guilder", "guilt", "guilty",
|
||||
"guinea", "guitar", "guitarist", "gum", "gumshoe", "gun", "gunpowder", "gutter", "guy", "gym", "gymnast", "gymnastics", "gynaecology",
|
||||
"gyro", "habit", "habitat", "hacienda", "hacksaw", "hackwork", "hail", "hair", "haircut", "hake", "half",
|
||||
@ -332,7 +332,7 @@ std::initializer_list<std::string_view> nouns
|
||||
"lemonade", "lemur", "lender", "lending", "length", "lens", "lentil", "leopard", "leprosy", "leptocephalus", "lesson", "letter",
|
||||
"lettuce", "level", "lever", "leverage", "leveret", "liability", "liar", "liberty", "libido", "library", "licence", "license", "licensing",
|
||||
"licorice", "lid", "lie", "lieu", "lieutenant", "life", "lifestyle", "lifetime", "lift", "ligand", "light", "lighting", "lightning",
|
||||
"lightscreen", "ligula", "likelihood", "likeness", "lilac", "lily", "limb", "lime", "limestone", "limit", "limitation", "limo", "line",
|
||||
"lightscreen", "ligula", "likelihood", "likeness", "lilac", "lily", "limb", "lime", "limestone", "limitation", "limo", "line",
|
||||
"linen", "liner", "linguist", "linguistics", "lining", "link", "linkage", "linseed", "lion", "lip", "lipid", "lipoprotein", "lipstick",
|
||||
"liquid", "liquidity", "liquor", "list", "listening", "listing", "literate", "literature", "litigation", "litmus", "litter", "littleneck",
|
||||
"liver", "livestock", "living", "lizard", "llama", "load", "loading", "loaf", "loafer", "loan", "lobby", "lobotomy", "lobster", "local",
|
||||
@ -386,7 +386,7 @@ std::initializer_list<std::string_view> nouns
|
||||
"offering", "office", "officer", "official", "offset", "oil", "okra", "oldie", "oleo", "olive", "omega", "omelet", "omission", "omnivore",
|
||||
"oncology", "onion", "online", "onset", "opening", "opera", "operating", "operation", "operator", "ophthalmologist", "opinion", "opium",
|
||||
"opossum", "opponent", "opportunist", "opportunity", "opposite", "opposition", "optimal", "optimisation", "optimist", "optimization",
|
||||
"option", "orange", "orangutan", "orator", "orchard", "orchestra", "orchid", "order", "ordinary", "ordination", "ore", "oregano", "organ",
|
||||
"option", "orange", "orangutan", "orator", "orchard", "orchestra", "orchid", "ordinary", "ordination", "ore", "oregano", "organ",
|
||||
"organisation", "organising", "organization", "organizing", "orient", "orientation", "origin", "original", "originality", "ornament",
|
||||
"osmosis", "osprey", "ostrich", "other", "otter", "ottoman", "ounce", "outback", "outcome", "outfielder", "outfit", "outhouse", "outlaw",
|
||||
"outlay", "outlet", "outline", "outlook", "output", "outrage", "outrigger", "outrun", "outset", "outside", "oval", "ovary", "oven", "overcharge",
|
||||
@ -532,7 +532,7 @@ std::initializer_list<std::string_view> nouns
|
||||
"suspenders", "suspension", "sustainment", "sustenance", "swallow", "swamp", "swan", "swanling", "swath", "sweat", "sweater", "sweatshirt",
|
||||
"sweatshop", "sweatsuit", "sweets", "swell", "swim", "swimming", "swimsuit", "swine", "swing", "switch", "switchboard", "switching",
|
||||
"swivel", "sword", "swordfight", "swordfish", "sycamore", "symbol", "symmetry", "sympathy", "symptom", "syndicate", "syndrome", "synergy",
|
||||
"synod", "synonym", "synthesis", "syrup", "system", "tab", "tabby", "tabernacle", "table", "tablecloth", "tablet", "tabletop",
|
||||
"synod", "synonym", "synthesis", "syrup", "system", "tab", "tabby", "tabernacle", "tablecloth", "tablet", "tabletop",
|
||||
"tachometer", "tackle", "taco", "tactics", "tactile", "tadpole", "tag", "tail", "tailbud", "tailor", "tailspin", "takeover",
|
||||
"tale", "talent", "talk", "talking", "tamale", "tambour", "tambourine", "tan", "tandem", "tangerine", "tank",
|
||||
"tanker", "tankful", "tap", "tape", "tapioca", "target", "taro", "tarragon", "tart", "task", "tassel", "taste", "tatami", "tattler",
|
||||
@ -564,7 +564,7 @@ std::initializer_list<std::string_view> nouns
|
||||
"tuxedo", "tweet", "tweezers", "twig", "twilight", "twine", "twins", "twist", "twister", "twitter", "type", "typeface", "typewriter",
|
||||
"typhoon", "ukulele", "ultimatum", "umbrella", "unblinking", "uncertainty", "uncle", "underclothes", "underestimate", "underground",
|
||||
"underneath", "underpants", "underpass", "undershirt", "understanding", "understatement", "undertaker", "underwear", "underweight", "underwire",
|
||||
"underwriting", "unemployment", "unibody", "uniform", "uniformity", "union", "unique", "unit", "unity", "universe", "university", "update",
|
||||
"underwriting", "unemployment", "unibody", "uniform", "uniformity", "unique", "unit", "unity", "universe", "university", "update",
|
||||
"upgrade", "uplift", "upper", "upstairs", "upward", "urge", "urgency", "urn", "usage", "use", "user", "usher", "usual", "utensil", "utilisation",
|
||||
"utility", "utilization", "vacation", "vaccine", "vacuum", "vagrant", "valance", "valentine", "validate", "validity", "valley", "valuable",
|
||||
"value", "vampire", "van", "vanadyl", "vane", "vanilla", "vanity", "variability", "variable", "variant", "variation", "variety", "vascular",
|
||||
|
@ -2,12 +2,14 @@
|
||||
#include <Storages/MergeTree/BoolMask.h>
|
||||
#include <DataTypes/DataTypesNumber.h>
|
||||
#include <DataTypes/FieldToDataType.h>
|
||||
#include <DataTypes/getLeastSupertype.h>
|
||||
#include <Interpreters/TreeRewriter.h>
|
||||
#include <Interpreters/ExpressionAnalyzer.h>
|
||||
#include <Interpreters/ExpressionActions.h>
|
||||
#include <Interpreters/castColumn.h>
|
||||
#include <Interpreters/misc.h>
|
||||
#include <Functions/FunctionFactory.h>
|
||||
#include <Functions/FunctionsConversion.h>
|
||||
#include <Functions/IFunction.h>
|
||||
#include <Common/FieldVisitorsAccurateComparison.h>
|
||||
#include <Common/typeid_cast.h>
|
||||
@ -23,7 +25,6 @@
|
||||
#include <cassert>
|
||||
#include <stack>
|
||||
|
||||
|
||||
namespace DB
|
||||
{
|
||||
|
||||
@ -975,9 +976,6 @@ bool KeyCondition::isKeyPossiblyWrappedByMonotonicFunctionsImpl(
|
||||
|
||||
static void castValueToType(const DataTypePtr & desired_type, Field & src_value, const DataTypePtr & src_type, const ASTPtr & node)
|
||||
{
|
||||
if (desired_type->equals(*src_type))
|
||||
return;
|
||||
|
||||
try
|
||||
{
|
||||
src_value = convertFieldToType(src_value, *desired_type, src_type.get());
|
||||
@ -1084,15 +1082,6 @@ bool KeyCondition::tryParseAtomFromAST(const ASTPtr & node, const Context & cont
|
||||
if (key_column_num == static_cast<size_t>(-1))
|
||||
throw Exception("`key_column_num` wasn't initialized. It is a bug.", ErrorCodes::LOGICAL_ERROR);
|
||||
|
||||
/// Transformed constant must weaken the condition, for example "x > 5" must weaken to "round(x) >= 5"
|
||||
if (is_constant_transformed)
|
||||
{
|
||||
if (func_name == "less")
|
||||
func_name = "lessOrEquals";
|
||||
else if (func_name == "greater")
|
||||
func_name = "greaterOrEquals";
|
||||
}
|
||||
|
||||
/// Replace <const> <sign> <data> on to <data> <-sign> <const>
|
||||
if (key_arg_pos == 1)
|
||||
{
|
||||
@ -1114,12 +1103,55 @@ bool KeyCondition::tryParseAtomFromAST(const ASTPtr & node, const Context & cont
|
||||
}
|
||||
}
|
||||
|
||||
bool cast_not_needed =
|
||||
is_set_const /// Set args are already casted inside Set::createFromAST
|
||||
|| (isNativeNumber(key_expr_type) && isNativeNumber(const_type)); /// Numbers are accurately compared without cast.
|
||||
bool cast_not_needed = is_set_const /// Set args are already casted inside Set::createFromAST
|
||||
|| ((isNativeNumber(key_expr_type) || isDateTime(key_expr_type))
|
||||
&& (isNativeNumber(const_type) || isDateTime(const_type))); /// Numbers and DateTime are accurately compared without cast.
|
||||
|
||||
if (!cast_not_needed && !key_expr_type->equals(*const_type))
|
||||
{
|
||||
if (const_value.getType() == Field::Types::String)
|
||||
{
|
||||
const_value = convertFieldToType(const_value, *key_expr_type);
|
||||
if (const_value.isNull())
|
||||
return false;
|
||||
// No need to set is_constant_transformed because we're doing exact conversion
|
||||
}
|
||||
else
|
||||
{
|
||||
DataTypePtr common_type = getLeastSupertype({key_expr_type, const_type});
|
||||
if (!const_type->equals(*common_type))
|
||||
{
|
||||
castValueToType(common_type, const_value, const_type, node);
|
||||
|
||||
// Need to set is_constant_transformed unless we're doing exact conversion
|
||||
if (!key_expr_type->equals(*common_type))
|
||||
is_constant_transformed = true;
|
||||
}
|
||||
if (!key_expr_type->equals(*common_type))
|
||||
{
|
||||
ColumnsWithTypeAndName arguments{
|
||||
{nullptr, key_expr_type, ""}, {DataTypeString().createColumnConst(1, common_type->getName()), common_type, ""}};
|
||||
FunctionOverloadResolverPtr func_builder_cast
|
||||
= std::make_shared<FunctionOverloadResolverAdaptor>(CastOverloadResolver::createImpl(false));
|
||||
auto func_cast = func_builder_cast->build(arguments);
|
||||
|
||||
/// If we know the given range only contains one value, then we treat all functions as positive monotonic.
|
||||
if (!func_cast || (!single_point && !func_cast->hasInformationAboutMonotonicity()))
|
||||
return false;
|
||||
chain.push_back(func_cast);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Transformed constant must weaken the condition, for example "x > 5" must weaken to "round(x) >= 5"
|
||||
if (is_constant_transformed)
|
||||
{
|
||||
if (func_name == "less")
|
||||
func_name = "lessOrEquals";
|
||||
else if (func_name == "greater")
|
||||
func_name = "greaterOrEquals";
|
||||
}
|
||||
|
||||
if (!cast_not_needed)
|
||||
castValueToType(key_expr_type, const_value, const_type, node);
|
||||
}
|
||||
else
|
||||
return false;
|
||||
|
@ -3895,7 +3895,7 @@ bool MergeTreeData::canUsePolymorphicParts(const MergeTreeSettings & settings, S
|
||||
|
||||
MergeTreeData::AlterConversions MergeTreeData::getAlterConversionsForPart(const MergeTreeDataPartPtr part) const
|
||||
{
|
||||
MutationCommands commands = getFirtsAlterMutationCommandsForPart(part);
|
||||
MutationCommands commands = getFirstAlterMutationCommandsForPart(part);
|
||||
|
||||
AlterConversions result{};
|
||||
for (const auto & command : commands)
|
||||
|
@ -905,7 +905,7 @@ protected:
|
||||
/// Used to receive AlterConversions for part and apply them on fly. This
|
||||
/// method has different implementations for replicated and non replicated
|
||||
/// MergeTree because they store mutations in different way.
|
||||
virtual MutationCommands getFirtsAlterMutationCommandsForPart(const DataPartPtr & part) const = 0;
|
||||
virtual MutationCommands getFirstAlterMutationCommandsForPart(const DataPartPtr & part) const = 0;
|
||||
/// Moves part to specified space, used in ALTER ... MOVE ... queries
|
||||
bool movePartsToSpace(const DataPartsVector & parts, SpacePtr space);
|
||||
|
||||
|
@ -47,7 +47,7 @@ std::optional<MutationCommand> MutationCommand::parse(ASTAlterCommand * command,
|
||||
for (const ASTPtr & assignment_ast : command->update_assignments->children)
|
||||
{
|
||||
const auto & assignment = assignment_ast->as<ASTAssignment &>();
|
||||
auto insertion = res.column_to_update_expression.emplace(assignment.column_name, assignment.expression);
|
||||
auto insertion = res.column_to_update_expression.emplace(assignment.column_name, assignment.expression());
|
||||
if (!insertion.second)
|
||||
throw Exception("Multiple assignments in the single statement to column " + backQuote(assignment.column_name),
|
||||
ErrorCodes::MULTIPLE_ASSIGNMENTS_TO_COLUMN);
|
||||
|
@ -793,7 +793,8 @@ bool StorageMergeTree::partIsAssignedToBackgroundOperation(const DataPartPtr & p
|
||||
return currently_merging_mutating_parts.count(part);
|
||||
}
|
||||
|
||||
std::shared_ptr<StorageMergeTree::MergeMutateSelectedEntry> StorageMergeTree::selectPartsToMutate(const StorageMetadataPtr & metadata_snapshot, String */* disable_reason */, TableLockHolder & /* table_lock_holder */)
|
||||
std::shared_ptr<StorageMergeTree::MergeMutateSelectedEntry> StorageMergeTree::selectPartsToMutate(
|
||||
const StorageMetadataPtr & metadata_snapshot, String * /* disable_reason */, TableLockHolder & /* table_lock_holder */)
|
||||
{
|
||||
std::lock_guard lock(currently_processing_in_background_mutex);
|
||||
size_t max_ast_elements = global_context.getSettingsRef().max_expanded_ast_elements;
|
||||
@ -1401,7 +1402,7 @@ CheckResults StorageMergeTree::checkData(const ASTPtr & query, const Context & c
|
||||
}
|
||||
|
||||
|
||||
MutationCommands StorageMergeTree::getFirtsAlterMutationCommandsForPart(const DataPartPtr & part) const
|
||||
MutationCommands StorageMergeTree::getFirstAlterMutationCommandsForPart(const DataPartPtr & part) const
|
||||
{
|
||||
std::lock_guard lock(currently_processing_in_background_mutex);
|
||||
|
||||
|
@ -231,7 +231,7 @@ protected:
|
||||
std::unique_ptr<MergeTreeSettings> settings_,
|
||||
bool has_force_restore_data_flag);
|
||||
|
||||
MutationCommands getFirtsAlterMutationCommandsForPart(const DataPartPtr & part) const override;
|
||||
MutationCommands getFirstAlterMutationCommandsForPart(const DataPartPtr & part) const override;
|
||||
};
|
||||
|
||||
}
|
||||
|
@ -6220,7 +6220,7 @@ bool StorageReplicatedMergeTree::canUseAdaptiveGranularity() const
|
||||
}
|
||||
|
||||
|
||||
MutationCommands StorageReplicatedMergeTree::getFirtsAlterMutationCommandsForPart(const DataPartPtr & part) const
|
||||
MutationCommands StorageReplicatedMergeTree::getFirstAlterMutationCommandsForPart(const DataPartPtr & part) const
|
||||
{
|
||||
return queue.getFirstAlterMutationCommandsForPart(part);
|
||||
}
|
||||
|
@ -584,7 +584,7 @@ private:
|
||||
void waitMutationToFinishOnReplicas(
|
||||
const Strings & replicas, const String & mutation_id) const;
|
||||
|
||||
MutationCommands getFirtsAlterMutationCommandsForPart(const DataPartPtr & part) const override;
|
||||
MutationCommands getFirstAlterMutationCommandsForPart(const DataPartPtr & part) const override;
|
||||
|
||||
void startBackgroundMovesIfNeeded() override;
|
||||
|
||||
|
@ -22,7 +22,7 @@ do
|
||||
break
|
||||
fi
|
||||
|
||||
if ! kill -0 -- $bg_query
|
||||
if ! kill -0 -- $bg_query 2>/dev/null
|
||||
then
|
||||
# The SELECT sleep(1) query finished earlier that we could grep for it in the process list, but it should have run for at least one second. It is Ok.
|
||||
break
|
||||
@ -30,8 +30,6 @@ do
|
||||
done
|
||||
|
||||
ps auxw | grep -F -- '--password' | grep -F hello ||:
|
||||
# Check that it is still running
|
||||
kill -0 -- $bg_query
|
||||
wait
|
||||
|
||||
# Once again with different syntax
|
||||
@ -46,7 +44,7 @@ do
|
||||
break
|
||||
fi
|
||||
|
||||
if ! kill -0 -- $bg_query
|
||||
if ! kill -0 -- $bg_query 2>/dev/null
|
||||
then
|
||||
# The SELECT sleep(1) query finished earlier that we could grep for it in the process list, but it should have run for at least one second. It is Ok.
|
||||
break
|
||||
@ -54,8 +52,6 @@ do
|
||||
done
|
||||
|
||||
ps auxw | grep -F -- '--password' | grep -F hello ||:
|
||||
# Check that it is still running
|
||||
kill -0 -- $bg_query
|
||||
wait
|
||||
|
||||
$CLICKHOUSE_CLIENT --query "DROP USER user"
|
||||
|
@ -54,14 +54,10 @@ FROM numbers(3)
|
||||
ORDER BY exp(number) ASC
|
||||
SELECT roundToExp2(number) AS x
|
||||
FROM numbers(3)
|
||||
ORDER BY
|
||||
number ASC,
|
||||
number ASC
|
||||
ORDER BY number ASC
|
||||
SELECT number AS x
|
||||
FROM numbers(3)
|
||||
ORDER BY
|
||||
number ASC,
|
||||
number ASC
|
||||
ORDER BY number ASC
|
||||
SELECT number
|
||||
FROM numbers(3)
|
||||
ORDER BY number DESC
|
||||
@ -79,9 +75,7 @@ FROM numbers(3)
|
||||
ORDER BY exp(number) DESC
|
||||
SELECT roundToExp2(number) AS x
|
||||
FROM numbers(3)
|
||||
ORDER BY
|
||||
number DESC,
|
||||
number DESC
|
||||
ORDER BY number DESC
|
||||
0
|
||||
1
|
||||
2
|
||||
|
@ -1,16 +1,16 @@
|
||||
SELECT 116, 'Qqfu://2020-02-10isqkc1203 sp 2000-05-27T18:38:01', 13e100, Residue_id_breakfastDevice, park(Innervation), avgIf(remote('128.0.0.1'))
|
||||
SELECT shell_dust_tintype between crumb and shoat, case when peach >= 116 then bombing else null end
|
||||
SELECT 116, 'Qqfu://2020-02-10isqkc1203 sp 2000-05-27T18:38:01', 13e100, Obsidian_id_diverTeam, sweets(Workplace), avgIf(remote('128.0.0.1'))
|
||||
SELECT treasury_mammoth_hazelnut between nutmeg and span, case when chive >= 116 then switching else null end
|
||||
|
||||
SELECT
|
||||
ChimeID,
|
||||
Testimonial.ID, Testimonial.SipCauseway,
|
||||
TankfulTRUMPET,
|
||||
HUMIDITY.TermiteName, HUMIDITY.TermiteSculptural, HUMIDITY.TermiteGuilt, HUMIDITY.TermiteIntensity, HUMIDITY.SipCauseway, HUMIDITY.Coat
|
||||
FROM merge.tinkle_efficiency
|
||||
EarthquakeID,
|
||||
Workout.ID, Workout.CoupleThrill,
|
||||
MedalEMPIRE,
|
||||
HOPE.ListingName, HOPE.ListingBomb, HOPE.ListingRamen, HOPE.ListingResult, HOPE.CoupleThrill, HOPE.Smile
|
||||
FROM merge.marsh_agreement
|
||||
WHERE
|
||||
FaithSeller >= '2020-10-13' AND FaithSeller <= '2020-10-21'
|
||||
AND MandolinID = 30750384
|
||||
AND intHash32(GafferID) = 448362928 AND intHash64(GafferID) = 12572659331310383983
|
||||
AND ChimeID IN (8195672321757027078, 7079643623150622129, 5057006826979676478, 7886875230160484653, 7494974311229040743)
|
||||
AND Stot = 1
|
||||
RecapitulationLeaver >= '2020-10-13' AND RecapitulationLeaver <= '2020-10-21'
|
||||
AND MasonryID = 30750384
|
||||
AND intHash32(EyeballID) = 448362928 AND intHash64(EyeballID) = 12572659331310383983
|
||||
AND EarthquakeID IN (8195672321757027078, 7079643623150622129, 5057006826979676478, 7886875230160484653, 7494974311229040743)
|
||||
AND Photography = 1
|
||||
|
||||
|
@ -0,0 +1 @@
|
||||
1 2
|
@ -0,0 +1,5 @@
|
||||
SET optimize_aggregators_of_group_by_keys = 1;
|
||||
SELECT source.key, max(target.key) FROM (SELECT 1 key, 'x' name) source
|
||||
INNER JOIN (SELECT 2 key, 'x' name) target
|
||||
ON source.name = target.name
|
||||
GROUP BY source.key;
|
@ -0,0 +1,46 @@
|
||||
SELECT
|
||||
timestamp,
|
||||
key
|
||||
FROM test_order_by
|
||||
ORDER BY timestamp ASC
|
||||
LIMIT 10
|
||||
Expression (Projection)
|
||||
Limit (preliminary LIMIT)
|
||||
MergingSorted (Merge sorted streams for ORDER BY)
|
||||
MergeSorting (Merge sorted blocks for ORDER BY)
|
||||
PartialSorting (Sort each block for ORDER BY)
|
||||
Expression (Before ORDER BY and SELECT)
|
||||
SettingQuotaAndLimits (Set limits and quota after reading from storage)
|
||||
ReadFromStorage (MergeTree)
|
||||
SELECT
|
||||
timestamp,
|
||||
key
|
||||
FROM test_order_by
|
||||
ORDER BY toDate(timestamp) ASC
|
||||
LIMIT 10
|
||||
Expression (Projection)
|
||||
Limit (preliminary LIMIT)
|
||||
FinishSorting
|
||||
Expression (Before ORDER BY and SELECT)
|
||||
SettingQuotaAndLimits (Set limits and quota after reading from storage)
|
||||
ReadFromStorage (MergeTree with order)
|
||||
SELECT
|
||||
timestamp,
|
||||
key
|
||||
FROM test_order_by
|
||||
ORDER BY
|
||||
toDate(timestamp) ASC,
|
||||
timestamp ASC
|
||||
LIMIT 10
|
||||
Expression (Projection)
|
||||
Limit (preliminary LIMIT)
|
||||
FinishSorting
|
||||
Expression (Before ORDER BY and SELECT)
|
||||
SettingQuotaAndLimits (Set limits and quota after reading from storage)
|
||||
ReadFromStorage (MergeTree with order)
|
||||
SELECT
|
||||
timestamp,
|
||||
key
|
||||
FROM test_order_by
|
||||
ORDER BY timestamp ASC
|
||||
LIMIT 10
|
@ -0,0 +1,26 @@
|
||||
SET optimize_monotonous_functions_in_order_by = 1;
|
||||
|
||||
DROP TABLE IF EXISTS test_order_by;
|
||||
|
||||
CREATE TABLE test_order_by (timestamp DateTime, key UInt32) ENGINE=MergeTree() ORDER BY (toDate(timestamp), key);
|
||||
INSERT INTO test_order_by SELECT now() + toIntervalSecond(number), number % 4 FROM numbers(10000);
|
||||
OPTIMIZE TABLE test_order_by FINAL;
|
||||
|
||||
EXPLAIN SYNTAX SELECT * FROM test_order_by ORDER BY timestamp LIMIT 10;
|
||||
EXPLAIN PLAN SELECT * FROM test_order_by ORDER BY timestamp LIMIT 10;
|
||||
|
||||
EXPLAIN SYNTAX SELECT * FROM test_order_by ORDER BY toDate(timestamp) LIMIT 10;
|
||||
EXPLAIN PLAN SELECT * FROM test_order_by ORDER BY toDate(timestamp) LIMIT 10;
|
||||
|
||||
EXPLAIN SYNTAX SELECT * FROM test_order_by ORDER BY toDate(timestamp), timestamp LIMIT 10;
|
||||
EXPLAIN PLAN SELECT * FROM test_order_by ORDER BY toDate(timestamp), timestamp LIMIT 10;
|
||||
|
||||
DROP TABLE IF EXISTS test_order_by;
|
||||
|
||||
CREATE TABLE test_order_by (timestamp DateTime, key UInt32) ENGINE=MergeTree() ORDER BY tuple();
|
||||
INSERT INTO test_order_by SELECT now() + toIntervalSecond(number), number % 4 FROM numbers(10000);
|
||||
OPTIMIZE TABLE test_order_by FINAL;
|
||||
|
||||
EXPLAIN SYNTAX SELECT * FROM test_order_by ORDER BY toDate(timestamp), timestamp LIMIT 10;
|
||||
|
||||
DROP TABLE IF EXISTS test_order_by;
|
@ -0,0 +1,5 @@
|
||||
1
|
||||
Array(Int64)
|
||||
Array(Int128)
|
||||
Array(Int128)
|
||||
Array(UInt256)
|
@ -0,0 +1,16 @@
|
||||
drop table if exists test_index;
|
||||
|
||||
create table test_index(date Date) engine MergeTree partition by toYYYYMM(date) order by date;
|
||||
|
||||
insert into test_index values('2020-10-30');
|
||||
|
||||
select 1 from test_index where date < toDateTime('2020-10-30 06:00:00');
|
||||
|
||||
drop table if exists test_index;
|
||||
|
||||
select toTypeName([-1, toUInt32(1)]);
|
||||
-- We don't promote to wide integers
|
||||
select toTypeName([-1, toUInt64(1)]); -- { serverError 386 }
|
||||
select toTypeName([-1, toInt128(1)]);
|
||||
select toTypeName([toInt64(-1), toInt128(1)]);
|
||||
select toTypeName([toUInt64(1), toUInt256(1)]);
|
@ -0,0 +1,3 @@
|
||||
1
|
||||
1
|
||||
1
|
@ -0,0 +1,21 @@
|
||||
DROP TABLE IF EXISTS realtimedrep;
|
||||
DROP TABLE IF EXISTS realtimedistributed;
|
||||
DROP TABLE IF EXISTS realtimebuff;
|
||||
|
||||
CREATE TABLE realtimedrep(amount Int64,transID String,userID String,appID String,appName String,transType String,orderSource String,nau String,fau String,transactionType String,supplier String,fMerchant String,bankConnCode String,reqDate DateTime) ENGINE = MergeTree PARTITION BY toDate(reqDate) ORDER BY transID SETTINGS index_granularity = 8192;
|
||||
CREATE TABLE realtimedistributed(amount Int64,transID String,userID String,appID String,appName String,transType String,orderSource String,nau String,fau String,transactionType String,supplier String,fMerchant String,bankConnCode String,reqDate DateTime) ENGINE = Distributed(test_cluster_two_shards, currentDatabase(), realtimedrep, rand());
|
||||
CREATE TABLE realtimebuff(amount Int64,transID String,userID String,appID String,appName String,transType String,orderSource String,nau String,fau String,transactionType String,supplier String,fMerchant String,bankConnCode String,reqDate DateTime) ENGINE = Buffer(currentDatabase(), 'realtimedistributed', 16, 3600, 36000, 10000, 1000000, 10000000, 100000000);
|
||||
|
||||
insert into realtimebuff (amount,transID,userID,appID,appName,transType,orderSource,nau,fau,transactionType,supplier,fMerchant,bankConnCode,reqDate) values (100, '200312000295032','200223000028708','14', 'Data','1', '20','1', '0','123','abc', '1234a','ZPVBIDV', 1598256583);
|
||||
|
||||
select sum(amount) = 100 from realtimebuff;
|
||||
|
||||
OPTIMIZE TABLE realtimebuff;
|
||||
select sum(amount) IN (100, 200) from realtimebuff;
|
||||
|
||||
SYSTEM FLUSH DISTRIBUTED realtimedistributed;
|
||||
select sum(amount) = 200 from realtimebuff;
|
||||
|
||||
DROP TABLE realtimedrep;
|
||||
DROP TABLE realtimedistributed;
|
||||
DROP TABLE realtimebuff;
|
111
tests/queries/0_stateless/01590_countSubstrings.reference
Normal file
111
tests/queries/0_stateless/01590_countSubstrings.reference
Normal file
@ -0,0 +1,111 @@
|
||||
|
||||
# countSubstrings
|
||||
|
||||
CountSubstringsImpl::constantConstant
|
||||
CountSubstringsImpl::constantConstantScalar
|
||||
empty
|
||||
0
|
||||
0
|
||||
0
|
||||
char
|
||||
1
|
||||
2
|
||||
3
|
||||
word
|
||||
1
|
||||
1
|
||||
1
|
||||
2
|
||||
3
|
||||
intersect
|
||||
2
|
||||
|
||||
CountSubstringsImpl::vectorVector
|
||||
1
|
||||
4
|
||||
6
|
||||
"intersect",4
|
||||
|
||||
CountSubstringsImpl::constantVector
|
||||
2
|
||||
1
|
||||
0
|
||||
3
|
||||
5
|
||||
"intersect",4
|
||||
|
||||
CountSubstringsImpl::vectorConstant
|
||||
0
|
||||
1
|
||||
2
|
||||
3
|
||||
4
|
||||
"intersect",4
|
||||
|
||||
# countSubstringsCaseInsensitive
|
||||
|
||||
CountSubstringsImpl::constantConstant
|
||||
CountSubstringsImpl::constantConstantScalar
|
||||
char
|
||||
1
|
||||
2
|
||||
3
|
||||
word
|
||||
1
|
||||
1
|
||||
1
|
||||
2
|
||||
3
|
||||
intersect
|
||||
2
|
||||
|
||||
CountSubstringsImpl::vectorVector
|
||||
1
|
||||
3
|
||||
5
|
||||
|
||||
CountSubstringsImpl::constantVector
|
||||
2
|
||||
1
|
||||
0
|
||||
3
|
||||
5
|
||||
|
||||
CountSubstringsImpl::vectorConstant
|
||||
1
|
||||
0
|
||||
0
|
||||
|
||||
# countSubstringsCaseInsensitiveUTF8
|
||||
|
||||
CountSubstringsImpl::constantConstant
|
||||
CountSubstringsImpl::constantConstantScalar
|
||||
char
|
||||
1
|
||||
2
|
||||
3
|
||||
word
|
||||
1
|
||||
1
|
||||
1
|
||||
2
|
||||
3
|
||||
intersect
|
||||
2
|
||||
|
||||
CountSubstringsImpl::vectorVector
|
||||
1
|
||||
3
|
||||
5
|
||||
"intersect",4
|
||||
|
||||
CountSubstringsImpl::constantVector
|
||||
2
|
||||
3
|
||||
5
|
||||
"intersect",4
|
||||
|
||||
CountSubstringsImpl::vectorConstant
|
||||
1
|
||||
0
|
||||
"intersect",4
|
138
tests/queries/0_stateless/01590_countSubstrings.sql
Normal file
138
tests/queries/0_stateless/01590_countSubstrings.sql
Normal file
@ -0,0 +1,138 @@
|
||||
--
|
||||
-- countSubstrings
|
||||
--
|
||||
select '';
|
||||
select '# countSubstrings';
|
||||
|
||||
select '';
|
||||
select 'CountSubstringsImpl::constantConstant';
|
||||
select 'CountSubstringsImpl::constantConstantScalar';
|
||||
|
||||
select 'empty';
|
||||
select countSubstrings('', '.');
|
||||
select countSubstrings('', '');
|
||||
select countSubstrings('.', '');
|
||||
|
||||
select 'char';
|
||||
select countSubstrings('foobar.com', '.');
|
||||
select countSubstrings('www.foobar.com', '.');
|
||||
select countSubstrings('.foobar.com.', '.');
|
||||
|
||||
select 'word';
|
||||
select countSubstrings('foobar.com', 'com');
|
||||
select countSubstrings('com.foobar', 'com');
|
||||
select countSubstrings('foo.com.bar', 'com');
|
||||
select countSubstrings('com.foobar.com', 'com');
|
||||
select countSubstrings('com.foo.com.bar.com', 'com');
|
||||
|
||||
select 'intersect';
|
||||
select countSubstrings('aaaa', 'aa');
|
||||
|
||||
select '';
|
||||
select 'CountSubstringsImpl::vectorVector';
|
||||
select countSubstrings(toString(number), toString(number)) from numbers(1);
|
||||
select countSubstrings(concat(toString(number), '000111'), toString(number)) from numbers(1);
|
||||
select countSubstrings(concat(toString(number), '000111001'), toString(number)) from numbers(1);
|
||||
select 'intersect', countSubstrings(concat(toString(number), '0000000'), '00') from numbers(1) format CSV;
|
||||
|
||||
select '';
|
||||
select 'CountSubstringsImpl::constantVector';
|
||||
select countSubstrings('100', toString(number)) from numbers(3);
|
||||
select countSubstrings('0100', toString(number)) from numbers(1);
|
||||
select countSubstrings('010000', toString(number)) from numbers(1);
|
||||
select 'intersect', countSubstrings('00000000', repeat(toString(number), 2)) from numbers(1) format CSV;
|
||||
|
||||
select '';
|
||||
select 'CountSubstringsImpl::vectorConstant';
|
||||
select countSubstrings(toString(number), '1') from system.numbers limit 3 offset 9;
|
||||
select countSubstrings(concat(toString(number), '000111'), '1') from numbers(1);
|
||||
select countSubstrings(concat(toString(number), '000111001'), '1') from numbers(1);
|
||||
select 'intersect', countSubstrings(repeat(toString(number), 8), '00') from numbers(1) format CSV;
|
||||
|
||||
--
|
||||
-- countSubstringsCaseInsensitive
|
||||
--
|
||||
select '';
|
||||
select '# countSubstringsCaseInsensitive';
|
||||
|
||||
select '';
|
||||
select 'CountSubstringsImpl::constantConstant';
|
||||
select 'CountSubstringsImpl::constantConstantScalar';
|
||||
|
||||
select 'char';
|
||||
select countSubstringsCaseInsensitive('aba', 'B');
|
||||
select countSubstringsCaseInsensitive('bab', 'B');
|
||||
select countSubstringsCaseInsensitive('BaBaB', 'b');
|
||||
|
||||
select 'word';
|
||||
select countSubstringsCaseInsensitive('foobar.com', 'COM');
|
||||
select countSubstringsCaseInsensitive('com.foobar', 'COM');
|
||||
select countSubstringsCaseInsensitive('foo.com.bar', 'COM');
|
||||
select countSubstringsCaseInsensitive('com.foobar.com', 'COM');
|
||||
select countSubstringsCaseInsensitive('com.foo.com.bar.com', 'COM');
|
||||
|
||||
select 'intersect';
|
||||
select countSubstringsCaseInsensitive('aaaa', 'AA');
|
||||
|
||||
select '';
|
||||
select 'CountSubstringsImpl::vectorVector';
|
||||
select countSubstringsCaseInsensitive(upper(char(number)), lower(char(number))) from numbers(100) where number = 0x41; -- A
|
||||
select countSubstringsCaseInsensitive(concat(toString(number), 'aaa111'), char(number)) from numbers(100) where number = 0x41;
|
||||
select countSubstringsCaseInsensitive(concat(toString(number), 'aaa111aa1'), char(number)) from numbers(100) where number = 0x41;
|
||||
|
||||
select '';
|
||||
select 'CountSubstringsImpl::constantVector';
|
||||
select countSubstringsCaseInsensitive('aab', char(number)) from numbers(100) where number >= 0x41 and number <= 0x43; -- A..C
|
||||
select countSubstringsCaseInsensitive('abaa', char(number)) from numbers(100) where number = 0x41;
|
||||
select countSubstringsCaseInsensitive('abaaaa', char(number)) from numbers(100) where number = 0x41;
|
||||
|
||||
select '';
|
||||
select 'CountSubstringsImpl::vectorConstant';
|
||||
select countSubstringsCaseInsensitive(char(number), 'a') from numbers(100) where number >= 0x41 and number <= 0x43;
|
||||
|
||||
--
|
||||
-- countSubstringsCaseInsensitiveUTF8
|
||||
--
|
||||
select '';
|
||||
select '# countSubstringsCaseInsensitiveUTF8';
|
||||
|
||||
select '';
|
||||
select 'CountSubstringsImpl::constantConstant';
|
||||
select 'CountSubstringsImpl::constantConstantScalar';
|
||||
|
||||
select 'char';
|
||||
select countSubstringsCaseInsensitiveUTF8('фуу', 'Ф');
|
||||
select countSubstringsCaseInsensitiveUTF8('ФуФ', 'ф');
|
||||
select countSubstringsCaseInsensitiveUTF8('ФуФуФ', 'ф');
|
||||
|
||||
select 'word';
|
||||
select countSubstringsCaseInsensitiveUTF8('подстрока.рф', 'РФ');
|
||||
select countSubstringsCaseInsensitiveUTF8('рф.подстрока', 'рф');
|
||||
select countSubstringsCaseInsensitiveUTF8('подстрока.рф.подстрока', 'РФ');
|
||||
select countSubstringsCaseInsensitiveUTF8('рф.подстрока.рф', 'рф');
|
||||
select countSubstringsCaseInsensitiveUTF8('рф.подстрока.рф.подстрока.рф', 'РФ');
|
||||
|
||||
select 'intersect';
|
||||
select countSubstringsCaseInsensitiveUTF8('яяяя', 'ЯЯ');
|
||||
|
||||
select '';
|
||||
select 'CountSubstringsImpl::vectorVector';
|
||||
-- can't use any char, since this will not make valid UTF8
|
||||
-- for the haystack we use number as-is, for needle we just add dependency from number to go to vectorVector code
|
||||
select countSubstringsCaseInsensitiveUTF8(upperUTF8(concat(char(number), 'я')), lowerUTF8(concat(substringUTF8(char(number), 2), 'Я'))) from numbers(100) where number = 0x41; -- A
|
||||
select countSubstringsCaseInsensitiveUTF8(concat(toString(number), 'ЯЯЯ111'), concat(substringUTF8(char(number), 2), 'я')) from numbers(100) where number = 0x41; -- A
|
||||
select countSubstringsCaseInsensitiveUTF8(concat(toString(number), 'яяя111яя1'), concat(substringUTF8(char(number), 2), 'Я')) from numbers(100) where number = 0x41; -- A
|
||||
select 'intersect', countSubstringsCaseInsensitiveUTF8(concat(toString(number), 'яяяяяяяя'), concat(substringUTF8(char(number), 2), 'Яя')) from numbers(100) where number = 0x41 format CSV; -- A
|
||||
|
||||
select '';
|
||||
select 'CountSubstringsImpl::constantVector';
|
||||
select countSubstringsCaseInsensitiveUTF8('ЯЯb', concat(substringUTF8(char(number), 2), 'я')) from numbers(100) where number = 0x41; -- A
|
||||
select countSubstringsCaseInsensitiveUTF8('ЯbЯЯ', concat(substringUTF8(char(number), 2), 'я')) from numbers(100) where number = 0x41; -- A
|
||||
select countSubstringsCaseInsensitiveUTF8('ЯbЯЯЯЯ', concat(substringUTF8(char(number), 2), 'я')) from numbers(100) where number = 0x41; -- A
|
||||
select 'intersect', countSubstringsCaseInsensitiveUTF8('ЯЯЯЯЯЯЯЯ', concat(substringUTF8(char(number), 2), 'Яя')) from numbers(100) where number = 0x41 format CSV; -- A
|
||||
|
||||
select '';
|
||||
select 'CountSubstringsImpl::vectorConstant';
|
||||
select countSubstringsCaseInsensitiveUTF8(concat(char(number), 'я'), 'Я') from numbers(100) where number = 0x41; -- A
|
||||
select countSubstringsCaseInsensitiveUTF8(concat(char(number), 'б'), 'Я') from numbers(100) where number = 0x41; -- A
|
||||
select 'intersect', countSubstringsCaseInsensitiveUTF8(concat(char(number), repeat('я', 8)), 'яЯ') from numbers(100) where number = 0x41 format CSV; -- A
|
@ -0,0 +1 @@
|
||||
00000000-0000-0000-0000-000000000000
|
29
tests/queries/0_stateless/01594_storage_join_uuid.sql
Normal file
29
tests/queries/0_stateless/01594_storage_join_uuid.sql
Normal file
@ -0,0 +1,29 @@
|
||||
-- the test from simPod, https://github.com/ClickHouse/ClickHouse/issues/5608
|
||||
|
||||
DROP TABLE IF EXISTS joint; -- the table name from the original issue.
|
||||
DROP TABLE IF EXISTS t;
|
||||
|
||||
CREATE TABLE IF NOT EXISTS joint
|
||||
(
|
||||
id UUID,
|
||||
value LowCardinality(String)
|
||||
)
|
||||
ENGINE = Join (ANY, LEFT, id);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS t
|
||||
(
|
||||
id UUID,
|
||||
d DateTime
|
||||
)
|
||||
ENGINE = MergeTree
|
||||
PARTITION BY toDate(d)
|
||||
ORDER BY id;
|
||||
|
||||
insert into joint VALUES ('00000000-0000-0000-0000-000000000000', 'yo');
|
||||
insert into t VALUES ('00000000-0000-0000-0000-000000000000', now());
|
||||
|
||||
SELECT id FROM t
|
||||
ANY LEFT JOIN joint ON t.id = joint.id;
|
||||
|
||||
DROP TABLE joint;
|
||||
DROP TABLE t;
|
@ -0,0 +1,6 @@
|
||||
UInt64 LowCardinality(UInt64) LowCardinality(String) String
|
||||
UInt64 LowCardinality(UInt64) LowCardinality(String) String
|
||||
UInt64 LowCardinality(UInt64) LowCardinality(String) String
|
||||
UInt64 LowCardinality(UInt64) LowCardinality(String) String
|
||||
UInt64 LowCardinality(UInt64) LowCardinality(String) String
|
||||
UInt64 LowCardinality(UInt64) LowCardinality(String) String
|
9
tests/queries/0_stateless/01596_full_join_chertus.sql
Normal file
9
tests/queries/0_stateless/01596_full_join_chertus.sql
Normal file
@ -0,0 +1,9 @@
|
||||
select toTypeName(materialize(js1.k)), toTypeName(materialize(js2.k)), toTypeName(materialize(js1.s)), toTypeName(materialize(js2.s))
|
||||
from (select number k, toLowCardinality(toString(number)) s from numbers(2)) as js1
|
||||
full join (select toLowCardinality(number+1) k, toString(number+1) s from numbers(2)) as js2
|
||||
using k order by js1.k, js2.k;
|
||||
|
||||
select toTypeName(js1.k), toTypeName(js2.k), toTypeName(js1.s), toTypeName(js2.s)
|
||||
from (select number k, toLowCardinality(toString(number)) s from numbers(2)) as js1
|
||||
full join (select toLowCardinality(number+1) k, toString(number+1) s from numbers(2)) as js2
|
||||
using k order by js1.k, js2.k;
|
@ -0,0 +1 @@
|
||||
1
|
6
tests/queries/0_stateless/01597_columns_list_ignored.sh
Executable file
6
tests/queries/0_stateless/01597_columns_list_ignored.sh
Executable file
@ -0,0 +1,6 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
CURDIR=$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)
|
||||
. "$CURDIR"/../shell_config.sh
|
||||
|
||||
${CLICKHOUSE_LOCAL} --query "describe table file('', TSV, 'a int, b.c int')" 2>&1 | grep -F -c 'Syntax error'
|
2
tests/queries/0_stateless/01598_memory_limit_zeros.sql
Normal file
2
tests/queries/0_stateless/01598_memory_limit_zeros.sql
Normal file
@ -0,0 +1,2 @@
|
||||
SET max_memory_usage = 1;
|
||||
select 'test', count(*) from zeros_mt(1000000) where not ignore(zero); -- { serverError 241 }
|
25
tests/queries/0_stateless/01599_multiline_input_and_singleline_comments.sh
Executable file
25
tests/queries/0_stateless/01599_multiline_input_and_singleline_comments.sh
Executable file
@ -0,0 +1,25 @@
|
||||
#!/usr/bin/expect -f
|
||||
|
||||
log_user 0
|
||||
set timeout 5
|
||||
match_max 100000
|
||||
|
||||
if ![info exists env(CLICKHOUSE_PORT_TCP)] {set env(CLICKHOUSE_PORT_TCP) 9000}
|
||||
|
||||
spawn clickhouse-client --multiline --port "$env(CLICKHOUSE_PORT_TCP)"
|
||||
expect ":) "
|
||||
|
||||
# Make a query
|
||||
send -- "SELECT 1\r"
|
||||
expect ":-] "
|
||||
send -- "-- xxx\r"
|
||||
expect ":-] "
|
||||
send -- ", 2\r"
|
||||
expect ":-] "
|
||||
send -- ";\r"
|
||||
|
||||
expect "│ 1 │ 2 │"
|
||||
expect ":) "
|
||||
|
||||
send -- "\4"
|
||||
expect eof
|
@ -0,0 +1,2 @@
|
||||
2 1
|
||||
1 1
|
32
tests/queries/0_stateless/01599_mutation_query_params.sh
Executable file
32
tests/queries/0_stateless/01599_mutation_query_params.sh
Executable file
@ -0,0 +1,32 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
CURDIR=$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)
|
||||
. "$CURDIR"/../shell_config.sh
|
||||
|
||||
|
||||
$CLICKHOUSE_CLIENT -n --query "
|
||||
DROP TABLE IF EXISTS test;
|
||||
|
||||
CREATE TABLE test
|
||||
(
|
||||
id UUID,
|
||||
date_time DateTime,
|
||||
x UInt32,
|
||||
y UInt32
|
||||
) ENGINE = MergeTree()
|
||||
PARTITION BY toYYYYMMDD(date_time)
|
||||
ORDER BY (date_time);
|
||||
|
||||
INSERT INTO test (x, y) VALUES (2, 1);
|
||||
"
|
||||
|
||||
$CLICKHOUSE_CLIENT --query "SELECT x, y FROM test"
|
||||
|
||||
$CLICKHOUSE_CLIENT --mutations_sync 1 --param_x 1 --param_y 1 --query "
|
||||
ALTER TABLE test
|
||||
UPDATE x = {x:UInt32}
|
||||
WHERE y = {y:UInt32};
|
||||
"
|
||||
|
||||
$CLICKHOUSE_CLIENT --query "SELECT x, y FROM test"
|
||||
$CLICKHOUSE_CLIENT --query "DROP TABLE test"
|
@ -167,9 +167,10 @@
|
||||
01548_query_log_query_execution_ms
|
||||
01552_dict_fixedstring
|
||||
01555_system_distribution_queue_mask
|
||||
01557_max_parallel_replicas_no_sample.sql
|
||||
01557_max_parallel_replicas_no_sample
|
||||
01525_select_with_offset_fetch_clause
|
||||
01560_timeseriesgroupsum_segfault
|
||||
00976_ttl_with_old_parts
|
||||
01584_distributed_buffer_cannot_find_column
|
||||
01018_ip_dictionary
|
||||
00976_ttl_with_old_parts
|
||||
|
Loading…
Reference in New Issue
Block a user