mirror of
https://github.com/ClickHouse/ClickHouse.git
synced 2024-11-23 16:12:01 +00:00
Merge pull request #26072 from vdimir/fix-offset-check-in-window-frame
Fix logical error with signed and unsigned offset in WindowFrame::checkValid
This commit is contained in:
commit
c98e131a81
@ -117,4 +117,16 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
class FieldVisitorAccurateLessOrEqual : public StaticVisitor<bool>
|
||||
{
|
||||
public:
|
||||
template <typename T, typename U>
|
||||
bool operator()(const T & l, const U & r) const
|
||||
{
|
||||
auto less_cmp = FieldVisitorAccurateLess();
|
||||
return !less_cmp(r, l);
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
@ -1,6 +1,7 @@
|
||||
#include <Interpreters/WindowDescription.h>
|
||||
|
||||
#include <Core/Field.h>
|
||||
#include <Common/FieldVisitorsAccurateComparison.h>
|
||||
#include <Common/FieldVisitorToString.h>
|
||||
#include <IO/Operators.h>
|
||||
#include <Parsers/ASTFunction.h>
|
||||
@ -99,7 +100,7 @@ void WindowFrame::checkValid() const
|
||||
&& begin_offset.get<Int64>() < INT_MAX))
|
||||
{
|
||||
throw Exception(ErrorCodes::BAD_ARGUMENTS,
|
||||
"Frame start offset for '{}' frame must be a nonnegative 32-bit integer, '{}' of type '{}' given.",
|
||||
"Frame start offset for '{}' frame must be a nonnegative 32-bit integer, '{}' of type '{}' given",
|
||||
toString(type),
|
||||
applyVisitor(FieldVisitorToString(), begin_offset),
|
||||
Field::Types::toString(begin_offset.getType()));
|
||||
@ -112,7 +113,7 @@ void WindowFrame::checkValid() const
|
||||
&& end_offset.get<Int64>() < INT_MAX))
|
||||
{
|
||||
throw Exception(ErrorCodes::BAD_ARGUMENTS,
|
||||
"Frame end offset for '{}' frame must be a nonnegative 32-bit integer, '{}' of type '{}' given.",
|
||||
"Frame end offset for '{}' frame must be a nonnegative 32-bit integer, '{}' of type '{}' given",
|
||||
toString(type),
|
||||
applyVisitor(FieldVisitorToString(), end_offset),
|
||||
Field::Types::toString(end_offset.getType()));
|
||||
@ -160,7 +161,8 @@ void WindowFrame::checkValid() const
|
||||
bool begin_less_equal_end;
|
||||
if (begin_preceding && end_preceding)
|
||||
{
|
||||
begin_less_equal_end = begin_offset >= end_offset;
|
||||
/// we can't compare Fields using operator<= if fields have different types
|
||||
begin_less_equal_end = applyVisitor(FieldVisitorAccurateLessOrEqual(), end_offset, begin_offset);
|
||||
}
|
||||
else if (begin_preceding && !end_preceding)
|
||||
{
|
||||
@ -172,7 +174,7 @@ void WindowFrame::checkValid() const
|
||||
}
|
||||
else /* if (!begin_preceding && !end_preceding) */
|
||||
{
|
||||
begin_less_equal_end = begin_offset <= end_offset;
|
||||
begin_less_equal_end = applyVisitor(FieldVisitorAccurateLessOrEqual(), begin_offset, end_offset);
|
||||
}
|
||||
|
||||
if (!begin_less_equal_end)
|
||||
|
@ -13,3 +13,5 @@ select count() over (rows between 1 + 1 preceding and 1 + 1 following) from numb
|
||||
5
|
||||
4
|
||||
3
|
||||
-- signed and unsigned in offset do not cause logical error
|
||||
select count() over (rows between 2 following and 1 + -1 following) FROM numbers(10); -- { serverError 36 }
|
||||
|
@ -4,3 +4,6 @@ set allow_experimental_window_functions = 1;
|
||||
|
||||
-- expressions in window frame
|
||||
select count() over (rows between 1 + 1 preceding and 1 + 1 following) from numbers(10);
|
||||
|
||||
-- signed and unsigned in offset do not cause logical error
|
||||
select count() over (rows between 2 following and 1 + -1 following) FROM numbers(10); -- { serverError 36 }
|
||||
|
Loading…
Reference in New Issue
Block a user