Merge branch 'master' into sentry-official-cpu-ram

This commit is contained in:
Alexey Milovidov 2020-11-30 09:40:10 +03:00
commit 97242e1fee
67 changed files with 1175 additions and 190 deletions

2
.gitmodules vendored
View File

@ -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

View File

@ -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.

View File

@ -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

@ -1 +1 @@
Subproject commit d63e1f016582e9faaaf279aa24513087a07bc6e7
Subproject commit 03781aaff0f10ef41f902b8cf865fe0067180c10

2
contrib/cassandra vendored

@ -1 +1 @@
Subproject commit a49b4e0e2696a4b8ef286a5b9538d1cbe8490509
Subproject commit d10187efb25b26da391def077edf3c6f2f3a23dd

2
contrib/librdkafka vendored

@ -1 +1 @@
Subproject commit 2090cbf56b715247ec2be7f768707a7ab1bf7ede
Subproject commit 9902bc4fb18bb441fa55ca154b341cdda191e5d3

@ -1 +1 @@
Subproject commit 1485b0de3eaa1508dfe49a5ba1e4aa2a71fd8335
Subproject commit e05523ca7c1fb8d095b612a1b1cfe96e199ffb17

2
contrib/openldap vendored

@ -1 +1 @@
Subproject commit 34b9ba94b30319ed6389a4e001d057f7983fe363
Subproject commit 0208811b6043ca06fda8631a5e473df1ec515ccb

2
contrib/poco vendored

@ -1 +1 @@
Subproject commit f49c6ab8d3aa71828bd1b411485c21722e8c9d82
Subproject commit f3d791f6568b99366d089b4479f76a515beb66d5

View File

@ -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/) |

View File

@ -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.

View File

@ -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-->

View File

@ -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`.

View File

@ -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())

View File

@ -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);

View 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);
}
};
}

View File

@ -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);
}

View File

@ -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);

View 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);
}
}

View 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>();
}
}

View 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>();
}
}

View File

@ -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);
}
}

View File

@ -208,6 +208,9 @@ SRCS(
cos.cpp
cosh.cpp
countDigits.cpp
countSubstrings.cpp
countSubstringsCaseInsensitive.cpp
countSubstringsCaseInsensitiveUTF8.cpp
currentDatabase.cpp
currentUser.cpp
dateDiff.cpp

View File

@ -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();

View File

@ -139,11 +139,6 @@ ExpressionAnalyzer::ExpressionAnalyzer(
analyzeAggregation();
}
bool ExpressionAnalyzer::isRemoteStorage() const
{
return storage() && storage()->isRemote();
}
void ExpressionAnalyzer::analyzeAggregation()
{

View File

@ -164,7 +164,7 @@ protected:
const ASTSelectQuery * getSelectQuery() const;
bool isRemoteStorage() const;
bool isRemoteStorage() const { return syntax->is_remote_storage; }
};
class SelectQueryExpressionAnalyzer;

View File

@ -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)

View File

@ -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);
};

View File

@ -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);

View File

@ -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);

View File

@ -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);
}
};

View File

@ -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;
}

View File

@ -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",

View File

@ -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;

View File

@ -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)

View File

@ -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);

View File

@ -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);

View File

@ -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);

View File

@ -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;
};
}

View File

@ -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);
}

View File

@ -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;

View File

@ -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"

View File

@ -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

View File

@ -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

View File

@ -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;

View File

@ -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

View File

@ -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;

View File

@ -0,0 +1,5 @@
1
Array(Int64)
Array(Int128)
Array(Int128)
Array(UInt256)

View File

@ -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)]);

View File

@ -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;

View 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

View 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

View File

@ -0,0 +1 @@
00000000-0000-0000-0000-000000000000

View 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;

View File

@ -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

View 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;

View File

@ -0,0 +1 @@
1

View 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'

View File

@ -0,0 +1,2 @@
SET max_memory_usage = 1;
select 'test', count(*) from zeros_mt(1000000) where not ignore(zero); -- { serverError 241 }

View 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

View File

@ -0,0 +1,2 @@
2 1
1 1

View 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"

View File

@ -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