Merge pull request #2840 from VadimPE/CLICKHOUSE-3211

CLICKHOUSE-3211 add TOP m, and OFFSET k
This commit is contained in:
alexey-milovidov 2018-08-14 12:55:12 +03:00 committed by GitHub
commit 6b3375393d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 59 additions and 0 deletions

View File

@ -380,6 +380,7 @@ namespace ErrorCodes
extern const int INVALID_JOIN_ON_EXPRESSION = 403;
extern const int BAD_ODBC_CONNECTION_STRING = 404;
extern const int PARTITION_SIZE_EXCEEDS_MAX_DROP_SIZE_LIMIT = 405;
extern const int TOP_AND_LIMIT_TOGETHER = 406;
extern const int KEEPER_EXCEPTION = 999;
extern const int POCO_EXCEPTION = 1000;

View File

@ -17,6 +17,7 @@ namespace DB
namespace ErrorCodes
{
extern const int SYNTAX_ERROR;
extern const int TOP_AND_LIMIT_TOGETHER;
}
@ -38,6 +39,8 @@ bool ParserSelectQuery::parseImpl(Pos & pos, ASTPtr & node, Expected & expected)
ParserKeyword s_limit("LIMIT");
ParserKeyword s_settings("SETTINGS");
ParserKeyword s_by("BY");
ParserKeyword s_top("TOP");
ParserKeyword s_offset("OFFSET");
ParserNotEmptyExpressionList exp_list(false);
ParserNotEmptyExpressionList exp_list_for_with_clause(false, true); /// Set prefer_alias_to_column_name for each alias.
@ -62,6 +65,26 @@ bool ParserSelectQuery::parseImpl(Pos & pos, ASTPtr & node, Expected & expected)
if (s_distinct.ignore(pos, expected))
select_query->distinct = true;
if (s_top.ignore(pos, expected))
{
ParserToken open_bracket(TokenType::OpeningRoundBracket);
ParserToken close_bracket(TokenType::ClosingRoundBracket);
ParserNumber num;
if (open_bracket.ignore(pos, expected))
{
if (!num.parse(pos, select_query->limit_length, expected))
return false;
if (!close_bracket.ignore(pos, expected))
return false;
}
else
{
if (!num.parse(pos, select_query->limit_length, expected))
return false;
}
}
if (!exp_list_for_select_clause.parse(pos, select_query->select_expression_list, expected))
return false;
}
@ -120,6 +143,9 @@ bool ParserSelectQuery::parseImpl(Pos & pos, ASTPtr & node, Expected & expected)
/// LIMIT length | LIMIT offset, length | LIMIT count BY expr-list
if (s_limit.ignore(pos, expected))
{
if (select_query->limit_length)
throw Exception("Can not use TOP and LIMIT together", ErrorCodes::TOP_AND_LIMIT_TOGETHER);
ParserToken s_comma(TokenType::Comma);
ParserNumber num;
@ -140,6 +166,11 @@ bool ParserSelectQuery::parseImpl(Pos & pos, ASTPtr & node, Expected & expected)
if (!exp_list.parse(pos, select_query->limit_by_expression_list, expected))
return false;
}
else if (s_offset.ignore(pos, expected))
{
if (!num.parse(pos, select_query->limit_offset, expected))
return false;
}
}
/// LIMIT length | LIMIT offset, length

View File

@ -0,0 +1,6 @@
1
2
1
2
3
4

View File

@ -0,0 +1,21 @@
DROP TABLE IF EXISTS test.test;
CREATE TABLE test.test(val Int64) engine = Memory;
INSERT INTO test.test VALUES (1);
INSERT INTO test.test VALUES (2);
INSERT INTO test.test VALUES (3);
INSERT INTO test.test VALUES (4);
INSERT INTO test.test VALUES (5);
INSERT INTO test.test VALUES (6);
INSERT INTO test.test VALUES (7);
INSERT INTO test.test VALUES (8);
INSERT INTO test.test VALUES (9);
SELECT TOP 2 * FROM test.test ORDER BY val;
SELECT TOP (2) * FROM test.test ORDER BY val;
SELECT * FROM test.test ORDER BY val LIMIT 2 OFFSET 2;
SELECT TOP 2 * FROM test.test ORDER BY val LIMIT 2; -- { clientError 406 }
SELECT * FROM test.test ORDER BY val LIMIT 2,3 OFFSET 2; -- { clientError 62 }
DROP TABLE test.test;