Skip to content

Commit ed2da41

Browse files
committed
Merge branch 'master' of github.com:ClickHouse/ClickHouse into dynamic-json-distinct-aggregate-functions
2 parents 2287f28 + 1c839ff commit ed2da41

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

42 files changed

+509
-59
lines changed

docs/en/interfaces/http.md

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ Connection: Close
5858
Content-Type: text/tab-separated-values; charset=UTF-8
5959
X-ClickHouse-Server-Display-Name: clickhouse.ru-central1.internal
6060
X-ClickHouse-Query-Id: 5abe861c-239c-467f-b955-8a201abb8b7f
61-
X-ClickHouse-Summary: {"read_rows":"0","read_bytes":"0","written_rows":"0","written_bytes":"0","total_rows_to_read":"0","elapsed_ns":"662334"}
61+
X-ClickHouse-Summary: {"read_rows":"0","read_bytes":"0","written_rows":"0","written_bytes":"0","total_rows_to_read":"0","elapsed_ns":"662334", "real_time_microseconds": "0"}
6262

6363
1
6464
```
@@ -472,7 +472,7 @@ $ curl -v 'http://localhost:8123/predefined_query'
472472
< X-ClickHouse-Format: Template
473473
< X-ClickHouse-Timezone: Asia/Shanghai
474474
< Keep-Alive: timeout=10
475-
< X-ClickHouse-Summary: {"read_rows":"0","read_bytes":"0","written_rows":"0","written_bytes":"0","total_rows_to_read":"0","elapsed_ns":"662334"}
475+
< X-ClickHouse-Summary: {"read_rows":"0","read_bytes":"0","written_rows":"0","written_bytes":"0","total_rows_to_read":"0","elapsed_ns":"662334", "real_time_microseconds":"0"}
476476
<
477477
# HELP "Query" "Number of executing queries"
478478
# TYPE "Query" counter
@@ -668,7 +668,7 @@ $ curl -vv -H 'XXX:xxx' 'http://localhost:8123/hi'
668668
< Content-Type: text/html; charset=UTF-8
669669
< Transfer-Encoding: chunked
670670
< Keep-Alive: timeout=10
671-
< X-ClickHouse-Summary: {"read_rows":"0","read_bytes":"0","written_rows":"0","written_bytes":"0","total_rows_to_read":"0","elapsed_ns":"662334"}
671+
< X-ClickHouse-Summary: {"read_rows":"0","read_bytes":"0","written_rows":"0","written_bytes":"0","total_rows_to_read":"0","elapsed_ns":"662334", "real_time_microseconds":"0"}
672672
<
673673
* Connection #0 to host localhost left intact
674674
Say Hi!%
@@ -708,7 +708,7 @@ $ curl -v -H 'XXX:xxx' 'http://localhost:8123/get_config_static_handler'
708708
< Content-Type: text/plain; charset=UTF-8
709709
< Transfer-Encoding: chunked
710710
< Keep-Alive: timeout=10
711-
< X-ClickHouse-Summary: {"read_rows":"0","read_bytes":"0","written_rows":"0","written_bytes":"0","total_rows_to_read":"0","elapsed_ns":"662334"}
711+
< X-ClickHouse-Summary: {"read_rows":"0","read_bytes":"0","written_rows":"0","written_bytes":"0","total_rows_to_read":"0","elapsed_ns":"662334", "real_time_microseconds":"0"}
712712
<
713713
* Connection #0 to host localhost left intact
714714
<html ng-app="SMI2"><head><base href="http://ui.tabix.io/"></head><body><div ui-view="" class="content-ui"></div><script src="http://loader.tabix.io/master.js"></script></body></html>%
@@ -766,7 +766,7 @@ $ curl -vv -H 'XXX:xxx' 'http://localhost:8123/get_absolute_path_static_handler'
766766
< Content-Type: text/html; charset=UTF-8
767767
< Transfer-Encoding: chunked
768768
< Keep-Alive: timeout=10
769-
< X-ClickHouse-Summary: {"read_rows":"0","read_bytes":"0","written_rows":"0","written_bytes":"0","total_rows_to_read":"0","elapsed_ns":"662334"}
769+
< X-ClickHouse-Summary: {"read_rows":"0","read_bytes":"0","written_rows":"0","written_bytes":"0","total_rows_to_read":"0","elapsed_ns":"662334", "real_time_microseconds":"0"}
770770
<
771771
<html><body>Absolute Path File</body></html>
772772
* Connection #0 to host localhost left intact
@@ -785,7 +785,7 @@ $ curl -vv -H 'XXX:xxx' 'http://localhost:8123/get_relative_path_static_handler'
785785
< Content-Type: text/html; charset=UTF-8
786786
< Transfer-Encoding: chunked
787787
< Keep-Alive: timeout=10
788-
< X-ClickHouse-Summary: {"read_rows":"0","read_bytes":"0","written_rows":"0","written_bytes":"0","total_rows_to_read":"0","elapsed_ns":"662334"}
788+
< X-ClickHouse-Summary: {"read_rows":"0","read_bytes":"0","written_rows":"0","written_bytes":"0","total_rows_to_read":"0","elapsed_ns":"662334", "real_time_microseconds":"0"}
789789
<
790790
<html><body>Relative Path File</body></html>
791791
* Connection #0 to host localhost left intact

docs/en/sql-reference/aggregate-functions/parametric-functions.md

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -104,7 +104,7 @@ Events that occur at the same second may lay in the sequence in an undefined ord
104104

105105
**Parameters**
106106

107-
- `pattern` — Pattern string. See [Pattern syntax](#sequencematch).
107+
- `pattern` — Pattern string. See [Pattern syntax](#pattern-syntax).
108108

109109
**Returned values**
110110

@@ -113,8 +113,7 @@ Events that occur at the same second may lay in the sequence in an undefined ord
113113

114114
Type: `UInt8`.
115115

116-
<a name="sequence-function-pattern-syntax"></a>
117-
**Pattern syntax**
116+
#### Pattern syntax
118117

119118
- `(?N)` — Matches the condition argument at position `N`. Conditions are numbered in the `[1, 32]` range. For example, `(?1)` matches the argument passed to the `cond1` parameter.
120119

@@ -196,7 +195,7 @@ sequenceCount(pattern)(timestamp, cond1, cond2, ...)
196195

197196
**Parameters**
198197

199-
- `pattern` — Pattern string. See [Pattern syntax](#sequencematch).
198+
- `pattern` — Pattern string. See [Pattern syntax](#pattern-syntax).
200199

201200
**Returned values**
202201

docs/en/sql-reference/data-types/newjson.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -453,8 +453,8 @@ As we can see, after inserting paths `e` and `f.g` the limit was reached and we
453453

454454
### During merges of data parts in MergeTree table engines
455455

456-
During merge of several data parts in MergeTree table the `JSON` column in the resulting data part can reach the limit of dynamic paths won't be able to store all paths from source parts as subcolumns.
457-
In this case ClickHouse chooses what paths will remain as subcolumns after merge and what types will be stored in the shared data structure. In most cases ClickHouse tries to keep paths that contains
456+
During merge of several data parts in MergeTree table the `JSON` column in the resulting data part can reach the limit of dynamic paths and won't be able to store all paths from source parts as subcolumns.
457+
In this case ClickHouse chooses what paths will remain as subcolumns after merge and what paths will be stored in the shared data structure. In most cases ClickHouse tries to keep paths that contain
458458
the largest number of non-null values and move the rarest paths to the shared data structure, but it depends on the implementation.
459459

460460
Let's see an example of such merge. First, let's create a table with `JSON` column, set the limit of dynamic paths to `3` and insert values with `5` different paths:

docs/en/sql-reference/functions/date-time-functions.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2019,7 +2019,7 @@ Alias: `dateTrunc`.
20192019

20202020
`unit` argument is case-insensitive.
20212021

2022-
- `value` — Date and time. [DateTime](../data-types/datetime.md) or [DateTime64](../data-types/datetime64.md).
2022+
- `value` — Date and time. [Date](../data-types/date.md), [Date32](../data-types/date32.md), [DateTime](../data-types/datetime.md) or [DateTime64](../data-types/datetime64.md).
20232023
- `timezone`[Timezone name](../../operations/server-configuration-parameters/settings.md#server_configuration_parameters-timezone) for the returned value (optional). If not specified, the function uses the timezone of the `value` parameter. [String](../data-types/string.md).
20242024

20252025
**Returned value**

docs/ru/interfaces/http.md

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ Connection: Close
5050
Content-Type: text/tab-separated-values; charset=UTF-8
5151
X-ClickHouse-Server-Display-Name: clickhouse.ru-central1.internal
5252
X-ClickHouse-Query-Id: 5abe861c-239c-467f-b955-8a201abb8b7f
53-
X-ClickHouse-Summary: {"read_rows":"0","read_bytes":"0","written_rows":"0","written_bytes":"0","total_rows_to_read":"0","elapsed_ns":"662334"}
53+
X-ClickHouse-Summary: {"read_rows":"0","read_bytes":"0","written_rows":"0","written_bytes":"0","total_rows_to_read":"0","elapsed_ns":"662334", "real_time_microseconds":"0"}
5454

5555
1
5656
```
@@ -367,7 +367,7 @@ $ curl -v 'http://localhost:8123/predefined_query'
367367
< X-ClickHouse-Format: Template
368368
< X-ClickHouse-Timezone: Asia/Shanghai
369369
< Keep-Alive: timeout=10
370-
< X-ClickHouse-Summary: {"read_rows":"0","read_bytes":"0","written_rows":"0","written_bytes":"0","total_rows_to_read":"0"}
370+
< X-ClickHouse-Summary: {"read_rows":"0","read_bytes":"0","written_rows":"0","written_bytes":"0","total_rows_to_read":"0", "elapsed_ns":"662334", "real_time_microseconds":"0"}
371371
<
372372
# HELP "Query" "Number of executing queries"
373373
# TYPE "Query" counter
@@ -601,7 +601,7 @@ $ curl -v -H 'XXX:xxx' 'http://localhost:8123/get_config_static_handler'
601601
< Content-Type: text/plain; charset=UTF-8
602602
< Transfer-Encoding: chunked
603603
< Keep-Alive: timeout=10
604-
< X-ClickHouse-Summary: {"read_rows":"0","read_bytes":"0","written_rows":"0","written_bytes":"0","total_rows_to_read":"0","elapsed_ns":"662334"}
604+
< X-ClickHouse-Summary: {"read_rows":"0","read_bytes":"0","written_rows":"0","written_bytes":"0","total_rows_to_read":"0","elapsed_ns":"662334", "real_time_microseconds":"0"}
605605
<
606606
* Connection #0 to host localhost left intact
607607
<html ng-app="SMI2"><head><base href="http://ui.tabix.io/"></head><body><div ui-view="" class="content-ui"></div><script src="http://loader.tabix.io/master.js"></script></body></html>%
@@ -659,7 +659,7 @@ $ curl -vv -H 'XXX:xxx' 'http://localhost:8123/get_absolute_path_static_handler'
659659
< Content-Type: text/html; charset=UTF-8
660660
< Transfer-Encoding: chunked
661661
< Keep-Alive: timeout=10
662-
< X-ClickHouse-Summary: {"read_rows":"0","read_bytes":"0","written_rows":"0","written_bytes":"0","total_rows_to_read":"0","elapsed_ns":"662334"}
662+
< X-ClickHouse-Summary: {"read_rows":"0","read_bytes":"0","written_rows":"0","written_bytes":"0","total_rows_to_read":"0","elapsed_ns":"662334", "real_time_microseconds":"0"}
663663
<
664664
<html><body>Absolute Path File</body></html>
665665
* Connection #0 to host localhost left intact
@@ -678,7 +678,7 @@ $ curl -vv -H 'XXX:xxx' 'http://localhost:8123/get_relative_path_static_handler'
678678
< Content-Type: text/html; charset=UTF-8
679679
< Transfer-Encoding: chunked
680680
< Keep-Alive: timeout=10
681-
< X-ClickHouse-Summary: {"read_rows":"0","read_bytes":"0","written_rows":"0","written_bytes":"0","total_rows_to_read":"0","elapsed_ns":"662334"}
681+
< X-ClickHouse-Summary: {"read_rows":"0","read_bytes":"0","written_rows":"0","written_bytes":"0","total_rows_to_read":"0","elapsed_ns":"662334", "real_time_microseconds":"0"}
682682
<
683683
<html><body>Relative Path File</body></html>
684684
* Connection #0 to host localhost left intact

docs/zh/interfaces/http.md

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ Connection: Close
5353
Content-Type: text/tab-separated-values; charset=UTF-8
5454
X-ClickHouse-Server-Display-Name: clickhouse.ru-central1.internal
5555
X-ClickHouse-Query-Id: 5abe861c-239c-467f-b955-8a201abb8b7f
56-
X-ClickHouse-Summary: {"read_rows":"0","read_bytes":"0","written_rows":"0","written_bytes":"0","total_rows_to_read":"0","elapsed_ns":"662334"}
56+
X-ClickHouse-Summary: {"read_rows":"0","read_bytes":"0","written_rows":"0","written_bytes":"0","total_rows_to_read":"0","elapsed_ns":"662334","real_time_microseconds":"0"}
5757

5858
1
5959
```
@@ -363,7 +363,7 @@ $ curl -v 'http://localhost:8123/predefined_query'
363363
< X-ClickHouse-Format: Template
364364
< X-ClickHouse-Timezone: Asia/Shanghai
365365
< Keep-Alive: timeout=10
366-
< X-ClickHouse-Summary: {"read_rows":"0","read_bytes":"0","written_rows":"0","written_bytes":"0","total_rows_to_read":"0","elapsed_ns":"662334"}
366+
< X-ClickHouse-Summary: {"read_rows":"0","read_bytes":"0","written_rows":"0","written_bytes":"0","total_rows_to_read":"0","elapsed_ns":"662334", "real_time_microseconds":"0"}
367367
<
368368
# HELP "Query" "Number of executing queries"
369369
# TYPE "Query" counter
@@ -524,7 +524,7 @@ $ curl -vv -H 'XXX:xxx' 'http://localhost:8123/hi'
524524
< Content-Type: text/html; charset=UTF-8
525525
< Transfer-Encoding: chunked
526526
< Keep-Alive: timeout=10
527-
< X-ClickHouse-Summary: {"read_rows":"0","read_bytes":"0","written_rows":"0","written_bytes":"0","total_rows_to_read":"0","elapsed_ns":"662334"}
527+
< X-ClickHouse-Summary: {"read_rows":"0","read_bytes":"0","written_rows":"0","written_bytes":"0","total_rows_to_read":"0","elapsed_ns":"662334", "real_time_microseconds":"0"}
528528
<
529529
* Connection #0 to host localhost left intact
530530
Say Hi!%
@@ -564,7 +564,7 @@ $ curl -v -H 'XXX:xxx' 'http://localhost:8123/get_config_static_handler'
564564
< Content-Type: text/plain; charset=UTF-8
565565
< Transfer-Encoding: chunked
566566
< Keep-Alive: timeout=10
567-
< X-ClickHouse-Summary: {"read_rows":"0","read_bytes":"0","written_rows":"0","written_bytes":"0","total_rows_to_read":"0","elapsed_ns":"662334"}
567+
< X-ClickHouse-Summary: {"read_rows":"0","read_bytes":"0","written_rows":"0","written_bytes":"0","total_rows_to_read":"0","elapsed_ns":"662334","real_time_microseconds":"0"}
568568
<
569569
* Connection #0 to host localhost left intact
570570
<html ng-app="SMI2"><head><base href="http://ui.tabix.io/"></head><body><div ui-view="" class="content-ui"></div><script src="http://loader.tabix.io/master.js"></script></body></html>%
@@ -616,7 +616,7 @@ $ curl -vv -H 'XXX:xxx' 'http://localhost:8123/get_absolute_path_static_handler'
616616
< Content-Type: text/html; charset=UTF-8
617617
< Transfer-Encoding: chunked
618618
< Keep-Alive: timeout=10
619-
< X-ClickHouse-Summary: {"read_rows":"0","read_bytes":"0","written_rows":"0","written_bytes":"0","total_rows_to_read":"0","elapsed_ns":"662334"}
619+
< X-ClickHouse-Summary: {"read_rows":"0","read_bytes":"0","written_rows":"0","written_bytes":"0","total_rows_to_read":"0","elapsed_ns":"662334","real_time_microseconds":"0"}
620620
<
621621
<html><body>Absolute Path File</body></html>
622622
* Connection #0 to host localhost left intact
@@ -635,7 +635,7 @@ $ curl -vv -H 'XXX:xxx' 'http://localhost:8123/get_relative_path_static_handler'
635635
< Content-Type: text/html; charset=UTF-8
636636
< Transfer-Encoding: chunked
637637
< Keep-Alive: timeout=10
638-
< X-ClickHouse-Summary: {"read_rows":"0","read_bytes":"0","written_rows":"0","written_bytes":"0","total_rows_to_read":"0","elapsed_ns":"662334"}
638+
< X-ClickHouse-Summary: {"read_rows":"0","read_bytes":"0","written_rows":"0","written_bytes":"0","total_rows_to_read":"0","elapsed_ns":"662334","real_time_microseconds":"0"}
639639
<
640640
<html><body>Relative Path File</body></html>
641641
* Connection #0 to host localhost left intact

programs/keeper-client/Commands.cpp

Lines changed: 118 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -677,4 +677,122 @@ void GetAllChildrenNumberCommand::execute(const ASTKeeperQuery * query, KeeperCl
677677
std::cout << totalNumChildren << "\n";
678678
}
679679

680+
namespace
681+
{
682+
683+
class CPMVOperation
684+
{
685+
constexpr static UInt64 kTryLimit = 1000;
686+
687+
public:
688+
CPMVOperation(String src_, String dest_, bool remove_src_, KeeperClient * client_)
689+
: src(std::move(src_)), dest(std::move(dest_)), remove_src(remove_src_), client(client_)
690+
{
691+
}
692+
693+
bool isTryLimitReached() const { return failed_tries_count >= kTryLimit; }
694+
695+
bool isCompleted() const { return is_completed; }
696+
697+
void perform()
698+
{
699+
Coordination::Stat src_stat;
700+
String data = client->zookeeper->get(src, &src_stat);
701+
702+
Coordination::Requests ops{
703+
zkutil::makeCheckRequest(src, src_stat.version),
704+
zkutil::makeCreateRequest(dest, data, zkutil::CreateMode::Persistent), // Do we need to copy ACLs here?
705+
};
706+
707+
if (remove_src)
708+
ops.push_back(zkutil::makeRemoveRequest(src, src_stat.version));
709+
710+
Coordination::Responses responses;
711+
auto code = client->zookeeper->tryMulti(ops, responses);
712+
713+
switch (code)
714+
{
715+
case Coordination::Error::ZOK: {
716+
is_completed = true;
717+
return;
718+
}
719+
case Coordination::Error::ZBADVERSION: {
720+
++failed_tries_count;
721+
722+
if (isTryLimitReached())
723+
zkutil::KeeperMultiException::check(code, ops, responses);
724+
725+
return;
726+
}
727+
default:
728+
zkutil::KeeperMultiException::check(code, ops, responses);
729+
}
730+
731+
throw Exception(ErrorCodes::LOGICAL_ERROR, "Unreachable");
732+
}
733+
734+
private:
735+
String src;
736+
String dest;
737+
bool remove_src = false;
738+
KeeperClient * client = nullptr;
739+
740+
bool is_completed = false;
741+
uint64_t failed_tries_count = 0;
742+
};
743+
744+
}
745+
746+
bool CPCommand::parse(IParser::Pos & pos, std::shared_ptr<ASTKeeperQuery> & node, [[maybe_unused]] Expected & expected) const
747+
{
748+
String src_path;
749+
if (!parseKeeperPath(pos, expected, src_path))
750+
return false;
751+
node->args.push_back(std::move(src_path));
752+
753+
String to_path;
754+
if (!parseKeeperPath(pos, expected, to_path))
755+
return false;
756+
node->args.push_back(std::move(to_path));
757+
758+
return true;
759+
}
760+
761+
void CPCommand::execute(const ASTKeeperQuery * query, KeeperClient * client) const
762+
{
763+
auto src = client->getAbsolutePath(query->args[0].safeGet<String>());
764+
auto dest = client->getAbsolutePath(query->args[1].safeGet<String>());
765+
766+
CPMVOperation operation(std::move(src), std::move(dest), /*remove_src_=*/false, /*client_=*/client);
767+
768+
while (!operation.isTryLimitReached() && !operation.isCompleted())
769+
operation.perform();
770+
}
771+
772+
bool MVCommand::parse(IParser::Pos & pos, std::shared_ptr<ASTKeeperQuery> & node, Expected & expected) const
773+
{
774+
String src_path;
775+
if (!parseKeeperPath(pos, expected, src_path))
776+
return false;
777+
node->args.push_back(std::move(src_path));
778+
779+
String to_path;
780+
if (!parseKeeperPath(pos, expected, to_path))
781+
return false;
782+
node->args.push_back(std::move(to_path));
783+
784+
return true;
785+
}
786+
787+
void MVCommand::execute(const ASTKeeperQuery * query, KeeperClient * client) const
788+
{
789+
auto src = client->getAbsolutePath(query->args[0].safeGet<String>());
790+
auto dest = client->getAbsolutePath(query->args[1].safeGet<String>());
791+
792+
CPMVOperation operation(std::move(src), std::move(dest), /*remove_src_=*/true, /*client_=*/client);
793+
794+
while (!operation.isTryLimitReached() && !operation.isCompleted())
795+
operation.perform();
796+
}
797+
680798
}

programs/keeper-client/Commands.h

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -266,4 +266,32 @@ class GetAllChildrenNumberCommand : public IKeeperClientCommand
266266
}
267267
};
268268

269+
class CPCommand : public IKeeperClientCommand
270+
{
271+
String getName() const override { return "cp"; }
272+
273+
bool parse(IParser::Pos & pos, std::shared_ptr<ASTKeeperQuery> & node, Expected & expected) const override;
274+
275+
void execute(const ASTKeeperQuery * query, KeeperClient * client) const override;
276+
277+
String getHelpMessage() const override
278+
{
279+
return "{} <src> <dest> -- Copies 'src' node to 'dest' path.";
280+
}
281+
};
282+
283+
class MVCommand : public IKeeperClientCommand
284+
{
285+
String getName() const override { return "mv"; }
286+
287+
bool parse(IParser::Pos & pos, std::shared_ptr<ASTKeeperQuery> & node, Expected & expected) const override;
288+
289+
void execute(const ASTKeeperQuery * query, KeeperClient * client) const override;
290+
291+
String getHelpMessage() const override
292+
{
293+
return "{} <src> <dest> -- Moves 'src' node to the 'dest' path.";
294+
}
295+
};
296+
269297
}

programs/keeper-client/KeeperClient.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -212,6 +212,8 @@ void KeeperClient::initialize(Poco::Util::Application & /* self */)
212212
std::make_shared<FourLetterWordCommand>(),
213213
std::make_shared<GetDirectChildrenNumberCommand>(),
214214
std::make_shared<GetAllChildrenNumberCommand>(),
215+
std::make_shared<CPCommand>(),
216+
std::make_shared<MVCommand>(),
215217
});
216218

217219
String home_path;

src/Client/ClientBase.cpp

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@
3434
#include <Parsers/Access/ASTCreateUserQuery.h>
3535
#include <Parsers/Access/ASTAuthenticationData.h>
3636
#include <Parsers/ASTDropQuery.h>
37+
#include <Parsers/ASTExplainQuery.h>
3738
#include <Parsers/ASTSelectQuery.h>
3839
#include <Parsers/ASTSetQuery.h>
3940
#include <Parsers/ASTUseQuery.h>
@@ -2111,6 +2112,15 @@ MultiQueryProcessingStage ClientBase::analyzeMultiQueryText(
21112112
// - Other formats (e.g. FORMAT CSV) are arbitrarily more complex and tricky to parse. For example, we may be unable to distinguish if the semicolon
21122113
// is part of the data or ends the statement. In this case, we simply assume that the end of the INSERT statement is determined by \n\n (two newlines).
21132114
auto * insert_ast = parsed_query->as<ASTInsertQuery>();
2115+
// We also consider the INSERT query in EXPLAIN queries (same as normal INSERT queries)
2116+
if (!insert_ast)
2117+
{
2118+
auto * explain_ast = parsed_query->as<ASTExplainQuery>();
2119+
if (explain_ast && explain_ast->getExplainedQuery())
2120+
{
2121+
insert_ast = explain_ast->getExplainedQuery()->as<ASTInsertQuery>();
2122+
}
2123+
}
21142124
const char * query_to_execute_end = this_query_end;
21152125
if (insert_ast && insert_ast->data)
21162126
{

0 commit comments

Comments
 (0)