mirror of
https://github.com/ClickHouse/ClickHouse.git
synced 2024-11-24 00:22:29 +00:00
Fix limit offset
This commit is contained in:
parent
2dc8d9fc1b
commit
868e86e9ed
@ -2,22 +2,23 @@
|
||||
|
||||
#include <Columns/getLeastSuperColumn.h>
|
||||
#include <Interpreters/Context.h>
|
||||
#include <Interpreters/InterpreterSelectIntersectExceptQuery.h>
|
||||
#include <Interpreters/InterpreterSelectQuery.h>
|
||||
#include <Interpreters/InterpreterSelectWithUnionQuery.h>
|
||||
#include <Interpreters/InterpreterSelectIntersectExceptQuery.h>
|
||||
#include <Interpreters/QueryLog.h>
|
||||
#include <Interpreters/evaluateConstantExpression.h>
|
||||
#include <Parsers/ASTSelectIntersectExceptQuery.h>
|
||||
#include <Parsers/ASTSelectQuery.h>
|
||||
#include <Parsers/ASTSelectWithUnionQuery.h>
|
||||
#include <Parsers/ASTSelectIntersectExceptQuery.h>
|
||||
#include <Parsers/queryToString.h>
|
||||
#include <Processors/QueryPlan/DistinctStep.h>
|
||||
#include <Processors/QueryPlan/ExpressionStep.h>
|
||||
#include <Processors/QueryPlan/IQueryPlanStep.h>
|
||||
#include <Processors/QueryPlan/QueryPlan.h>
|
||||
#include <Processors/QueryPlan/UnionStep.h>
|
||||
#include <Processors/QueryPlan/LimitStep.h>
|
||||
#include <Processors/QueryPlan/OffsetStep.h>
|
||||
#include <Processors/QueryPlan/Optimizations/QueryPlanOptimizationSettings.h>
|
||||
#include <Processors/QueryPlan/QueryPlan.h>
|
||||
#include <Processors/QueryPlan/UnionStep.h>
|
||||
#include <QueryPipeline/QueryPipelineBuilder.h>
|
||||
#include <Common/typeid_cast.h>
|
||||
|
||||
@ -106,32 +107,35 @@ InterpreterSelectWithUnionQuery::InterpreterSelectWithUnionQuery(
|
||||
const ASTPtr limit_offset_ast = select_query->limitOffset();
|
||||
if (limit_offset_ast)
|
||||
{
|
||||
limit_offset = limit_offset_ast->as<ASTLiteral &>().value.safeGet<UInt64>();
|
||||
limit_offset = evaluateConstantExpressionAsLiteral(limit_offset_ast, context)->as<ASTLiteral &>().value.safeGet<UInt64>();
|
||||
UInt64 new_limit_offset = settings.offset + limit_offset;
|
||||
limit_offset_ast->as<ASTLiteral &>().value = Field(new_limit_offset);
|
||||
ASTPtr new_limit_offset_ast = std::make_shared<ASTLiteral>(new_limit_offset);
|
||||
select_query->setExpression(ASTSelectQuery::Expression::LIMIT_OFFSET, std::move(new_limit_offset_ast));
|
||||
}
|
||||
else if (settings.offset)
|
||||
{
|
||||
ASTPtr new_limit_offset_ast = std::make_shared<ASTLiteral>(Field(static_cast<UInt64>(settings.offset)));
|
||||
ASTPtr new_limit_offset_ast = std::make_shared<ASTLiteral>(settings.offset.value);
|
||||
select_query->setExpression(ASTSelectQuery::Expression::LIMIT_OFFSET, std::move(new_limit_offset_ast));
|
||||
}
|
||||
|
||||
const ASTPtr limit_length_ast = select_query->limitLength();
|
||||
if (limit_length_ast)
|
||||
{
|
||||
limit_length = limit_length_ast->as<ASTLiteral &>().value.safeGet<UInt64>();
|
||||
limit_length = evaluateConstantExpressionAsLiteral(limit_length_ast, context)->as<ASTLiteral &>().value.safeGet<UInt64>();
|
||||
|
||||
UInt64 new_limit_length = 0;
|
||||
if (settings.offset == 0)
|
||||
new_limit_length = std::min(limit_length, static_cast<UInt64>(settings.limit));
|
||||
new_limit_length = std::min(limit_length, settings.limit.value);
|
||||
else if (settings.offset < limit_length)
|
||||
new_limit_length = settings.limit ? std::min(static_cast<UInt64>(settings.limit), limit_length - settings.offset) : (limit_length - settings.offset);
|
||||
new_limit_length = settings.limit ? std::min(settings.limit.value, limit_length - settings.offset.value)
|
||||
: (limit_length - settings.offset.value);
|
||||
|
||||
limit_length_ast->as<ASTLiteral &>().value = Field(new_limit_length);
|
||||
ASTPtr new_limit_length_ast = std::make_shared<ASTLiteral>(new_limit_length);
|
||||
select_query->setExpression(ASTSelectQuery::Expression::LIMIT_LENGTH, std::move(new_limit_length_ast));
|
||||
}
|
||||
else if (settings.limit)
|
||||
{
|
||||
ASTPtr new_limit_length_ast = std::make_shared<ASTLiteral>(Field(static_cast<UInt64>(settings.limit)));
|
||||
ASTPtr new_limit_length_ast = std::make_shared<ASTLiteral>(settings.limit.value);
|
||||
select_query->setExpression(ASTSelectQuery::Expression::LIMIT_LENGTH, std::move(new_limit_length_ast));
|
||||
}
|
||||
|
||||
|
@ -22,6 +22,10 @@
|
||||
107
|
||||
108
|
||||
109
|
||||
102
|
||||
103
|
||||
104
|
||||
105
|
||||
105
|
||||
106
|
||||
107
|
||||
@ -38,6 +42,26 @@
|
||||
64
|
||||
64
|
||||
60
|
||||
60
|
||||
60
|
||||
61
|
||||
61
|
||||
62
|
||||
62
|
||||
63
|
||||
63
|
||||
64
|
||||
64
|
||||
60
|
||||
60
|
||||
61
|
||||
61
|
||||
62
|
||||
62
|
||||
63
|
||||
63
|
||||
64
|
||||
64
|
||||
35
|
||||
35
|
||||
36
|
||||
|
@ -11,6 +11,7 @@ SELECT * FROM test OFFSET 20; -- 5 rows
|
||||
SELECT * FROM (SELECT i FROM test LIMIT 10 OFFSET 50) TMP; -- 5 rows
|
||||
SELECT * FROM test LIMIT 4 OFFSET 192; -- 4 rows
|
||||
SELECT * FROM test LIMIT 10 OFFSET 195; -- 5 rows
|
||||
SELECT * FROM test LIMIT 2*2 OFFSET 192;
|
||||
|
||||
-- Only set offset
|
||||
SET limit = 0;
|
||||
@ -21,6 +22,8 @@ SELECT * FROM test LIMIT 100; -- no result
|
||||
SET offset = 10;
|
||||
SELECT * FROM test LIMIT 20 OFFSET 100; -- 10 rows
|
||||
SELECT * FROM test LIMIT 11 OFFSET 100; -- 1 rows
|
||||
SELECT * FROM test LIMIT 20 OFFSET 10*10;
|
||||
SELECT * FROM test LIMIT 4*5 OFFSET 10*10;
|
||||
|
||||
-- offset and limit together
|
||||
SET limit = 10;
|
||||
|
Loading…
Reference in New Issue
Block a user