mirror of
https://github.com/ClickHouse/ClickHouse.git
synced 2024-11-27 10:02:01 +00:00
Merge branch 'master' into async-loader-integration
This commit is contained in:
commit
2c47bb2a22
@ -34,7 +34,13 @@ The binary you just downloaded can run all sorts of ClickHouse tools and utiliti
|
||||
|
||||
A common use of `clickhouse-local` is to run ad-hoc queries on files: where you don't have to insert the data into a table. `clickhouse-local` can stream the data from a file into a temporary table and execute your SQL.
|
||||
|
||||
If the file is sitting on the same machine as `clickhouse-local`, use the `file` table engine. The following `reviews.tsv` file contains a sampling of Amazon product reviews:
|
||||
If the file is sitting on the same machine as `clickhouse-local`, you can simple specify the file to load. The following `reviews.tsv` file contains a sampling of Amazon product reviews:
|
||||
|
||||
```bash
|
||||
./clickhouse local -q "SELECT * FROM 'reviews.tsv'"
|
||||
```
|
||||
|
||||
This command is a shortcut of:
|
||||
|
||||
```bash
|
||||
./clickhouse local -q "SELECT * FROM file('reviews.tsv')"
|
||||
|
@ -35,6 +35,18 @@ LocalConnection::LocalConnection(ContextPtr context_, bool send_progress_, bool
|
||||
|
||||
LocalConnection::~LocalConnection()
|
||||
{
|
||||
/// Last query may not have been finished or cancelled due to exception on client side.
|
||||
if (state && !state->is_finished && !state->is_cancelled)
|
||||
{
|
||||
try
|
||||
{
|
||||
LocalConnection::sendCancel();
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
/// Just ignore any exception.
|
||||
}
|
||||
}
|
||||
state.reset();
|
||||
}
|
||||
|
||||
@ -73,6 +85,10 @@ void LocalConnection::sendQuery(
|
||||
bool,
|
||||
std::function<void(const Progress &)> process_progress_callback)
|
||||
{
|
||||
/// Last query may not have been finished or cancelled due to exception on client side.
|
||||
if (state && !state->is_finished && !state->is_cancelled)
|
||||
sendCancel();
|
||||
|
||||
/// Suggestion comes without client_info.
|
||||
if (client_info)
|
||||
query_context = session.makeQueryContext(*client_info);
|
||||
@ -204,6 +220,10 @@ void LocalConnection::sendCancel()
|
||||
state->is_cancelled = true;
|
||||
if (state->executor)
|
||||
state->executor->cancel();
|
||||
if (state->pushing_executor)
|
||||
state->pushing_executor->cancel();
|
||||
if (state->pushing_async_executor)
|
||||
state->pushing_async_executor->cancel();
|
||||
}
|
||||
|
||||
bool LocalConnection::pullBlock(Block & block)
|
||||
|
@ -243,6 +243,38 @@ bool ParserIdentifier::parseImpl(Pos & pos, ASTPtr & node, Expected & expected)
|
||||
}
|
||||
|
||||
|
||||
bool ParserTableAsStringLiteralIdentifier::parseImpl(Pos & pos, ASTPtr & node, Expected & expected)
|
||||
{
|
||||
if (pos->type != TokenType::StringLiteral)
|
||||
return false;
|
||||
|
||||
ReadBufferFromMemory in(pos->begin, pos->size());
|
||||
String s;
|
||||
|
||||
if (!tryReadQuotedStringInto(s, in))
|
||||
{
|
||||
expected.add(pos, "string literal");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (in.count() != pos->size())
|
||||
{
|
||||
expected.add(pos, "string literal");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (s.empty())
|
||||
{
|
||||
expected.add(pos, "non-empty string literal");
|
||||
return false;
|
||||
}
|
||||
|
||||
node = std::make_shared<ASTTableIdentifier>(s);
|
||||
++pos;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool ParserCompoundIdentifier::parseImpl(Pos & pos, ASTPtr & node, Expected & expected)
|
||||
{
|
||||
ASTPtr id_list;
|
||||
|
@ -34,6 +34,19 @@ protected:
|
||||
};
|
||||
|
||||
|
||||
/** An identifier for tables written as string literal, for example, 'mytable.avro'
|
||||
*/
|
||||
class ParserTableAsStringLiteralIdentifier : public IParserBase
|
||||
{
|
||||
public:
|
||||
explicit ParserTableAsStringLiteralIdentifier() {}
|
||||
|
||||
protected:
|
||||
const char * getName() const override { return "string literal table identifier"; }
|
||||
bool parseImpl(Pos & pos, ASTPtr & node, Expected & expected) override;
|
||||
};
|
||||
|
||||
|
||||
/** An identifier, possibly containing a dot, for example, x_yz123 or `something special` or Hits.EventTime,
|
||||
* possibly with UUID clause like `db name`.`table name` UUID 'xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx'
|
||||
*/
|
||||
|
@ -24,6 +24,8 @@ bool ParserTableExpression::parseImpl(Pos & pos, ASTPtr & node, Expected & expec
|
||||
if (!ParserWithOptionalAlias(std::make_unique<ParserSubquery>(), allow_alias_without_as_keyword).parse(pos, res->subquery, expected)
|
||||
&& !ParserWithOptionalAlias(std::make_unique<ParserFunction>(false, true), allow_alias_without_as_keyword).parse(pos, res->table_function, expected)
|
||||
&& !ParserWithOptionalAlias(std::make_unique<ParserCompoundIdentifier>(true, true), allow_alias_without_as_keyword)
|
||||
.parse(pos, res->database_and_table_name, expected)
|
||||
&& !ParserWithOptionalAlias(std::make_unique<ParserTableAsStringLiteralIdentifier>(), allow_alias_without_as_keyword)
|
||||
.parse(pos, res->database_and_table_name, expected))
|
||||
return false;
|
||||
|
||||
|
@ -0,0 +1,27 @@
|
||||
Test 1: check double quotes
|
||||
1 abc 123 abacaba
|
||||
2 def 456 bacabaa
|
||||
3 story 78912 acabaab
|
||||
4 history 21321321 cabaaba
|
||||
Test 1a: check double quotes no parsing overflow
|
||||
1
|
||||
Test 1b: check double quotes empty
|
||||
1
|
||||
Test 2: check back quotes
|
||||
1 abc 123 abacaba
|
||||
2 def 456 bacabaa
|
||||
3 story 78912 acabaab
|
||||
4 history 21321321 cabaaba
|
||||
Test 2a: check back quotes no parsing overflow
|
||||
1
|
||||
Test 2b: check back quotes empty
|
||||
1
|
||||
Test 3: check literal
|
||||
1 abc 123 abacaba
|
||||
2 def 456 bacabaa
|
||||
3 story 78912 acabaab
|
||||
4 history 21321321 cabaaba
|
||||
Test 3a: check literal no parsing overflow
|
||||
1
|
||||
Test 3b: check literal empty
|
||||
1
|
56
tests/queries/0_stateless/02816_clickhouse_local_table_name_expressions.sh
Executable file
56
tests/queries/0_stateless/02816_clickhouse_local_table_name_expressions.sh
Executable file
@ -0,0 +1,56 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
CURDIR=$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)
|
||||
# shellcheck source=../shell_config.sh
|
||||
. "$CURDIR"/../shell_config.sh
|
||||
|
||||
dir=${CLICKHOUSE_TEST_UNIQUE_NAME}
|
||||
[[ -d $dir ]] && rm -rd $dir
|
||||
mkdir $dir
|
||||
|
||||
# Create temporary csv file for tests
|
||||
echo '"id","str","int","text"' > $dir/tmp.csv
|
||||
echo '1,"abc",123,"abacaba"' >> $dir/tmp.csv
|
||||
echo '2,"def",456,"bacabaa"' >> $dir/tmp.csv
|
||||
echo '3,"story",78912,"acabaab"' >> $dir/tmp.csv
|
||||
echo '4,"history",21321321,"cabaaba"' >> $dir/tmp.csv
|
||||
|
||||
#################
|
||||
echo "Test 1: check double quotes"
|
||||
|
||||
$CLICKHOUSE_LOCAL -q "SELECT * FROM \"${dir}/tmp.csv\""
|
||||
#################
|
||||
echo "Test 1a: check double quotes no parsing overflow"
|
||||
|
||||
$CLICKHOUSE_LOCAL -q "SELECT * FROM \"${dir}/tmp.csv\"\"bad\"" 2>&1 | grep -c "UNKNOWN_TABLE"
|
||||
#################
|
||||
echo "Test 1b: check double quotes empty"
|
||||
|
||||
$CLICKHOUSE_LOCAL -q "SELECT * FROM \"\"" 2>&1 | grep -c "SYNTAX_ERROR"
|
||||
#################
|
||||
echo "Test 2: check back quotes"
|
||||
|
||||
$CLICKHOUSE_LOCAL -q "SELECT * FROM \`${dir}/tmp.csv\`"
|
||||
#################
|
||||
echo "Test 2a: check back quotes no parsing overflow"
|
||||
|
||||
$CLICKHOUSE_LOCAL -q "SELECT * FROM \`${dir}/tmp.csv\`\`bad\`" 2>&1 | grep -c "UNKNOWN_TABLE"
|
||||
#################
|
||||
echo "Test 2b: check back quotes empty"
|
||||
|
||||
$CLICKHOUSE_LOCAL -q "SELECT * FROM \`\`" 2>&1 | grep -c "SYNTAX_ERROR"
|
||||
#################
|
||||
echo "Test 3: check literal"
|
||||
|
||||
$CLICKHOUSE_LOCAL -q "SELECT * FROM '${dir}/tmp.csv'"
|
||||
#################
|
||||
echo "Test 3a: check literal no parsing overflow"
|
||||
|
||||
$CLICKHOUSE_LOCAL -q "SELECT * FROM '${dir}/tmp.csv''bad'" 2>&1 | grep -c "SYNTAX_ERROR"
|
||||
#################
|
||||
echo "Test 3b: check literal empty"
|
||||
|
||||
$CLICKHOUSE_LOCAL -q "SELECT * FROM ''" 2>&1 | grep -c "SYNTAX_ERROR"
|
||||
|
||||
# Remove temporary dir with files
|
||||
rm -rd $dir
|
1
tests/queries/0_stateless/02841_local_assert.reference
Normal file
1
tests/queries/0_stateless/02841_local_assert.reference
Normal file
@ -0,0 +1 @@
|
||||
1
|
18
tests/queries/0_stateless/02841_local_assert.sh
Executable file
18
tests/queries/0_stateless/02841_local_assert.sh
Executable file
@ -0,0 +1,18 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
set -e
|
||||
|
||||
CUR_DIR=$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)
|
||||
# shellcheck source=../shell_config.sh
|
||||
. "$CUR_DIR"/../shell_config.sh
|
||||
|
||||
echo "create table test (x UInt64) engine=Memory;
|
||||
insert into test from infile 'data'; -- {clientError BAD_ARGUMENTS}" | $CLICKHOUSE_LOCAL -nm
|
||||
|
||||
echo "create table test (x UInt64) engine=Memory;
|
||||
insert into test from infile 'data';" | $CLICKHOUSE_LOCAL -nm --ignore-error
|
||||
|
||||
echo "create table test (x UInt64) engine=Memory;
|
||||
insert into test from infile 'data'; -- {clientError BAD_ARGUMENTS}
|
||||
select 1" | $CLICKHOUSE_LOCAL -nm
|
||||
|
Loading…
Reference in New Issue
Block a user