mirror of
https://github.com/ClickHouse/ClickHouse.git
synced 2024-11-21 23:21:59 +00:00
frame grammar tmp
This commit is contained in:
parent
d0922e2985
commit
f346a9bf8b
@ -39,6 +39,26 @@ struct WindowFunctionDescription
|
||||
std::string dump() const;
|
||||
};
|
||||
|
||||
struct WindowFrame
|
||||
{
|
||||
enum class FrameType { Rows, Groups, Range };
|
||||
enum class OffsetType { Unbounded, Current, Offset };
|
||||
|
||||
// This flag signifies that the frame properties were not set explicitly by
|
||||
// user, but the fields of this structure still have to contain proper values
|
||||
// for the default frame of ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW.
|
||||
bool is_default = true;
|
||||
|
||||
FrameType type = FrameType::Rows;
|
||||
|
||||
/*
|
||||
* We don't need these yet.
|
||||
* OffsetType begin_offset = Unbounded;
|
||||
|
||||
* OffsetType end_offset = Current;
|
||||
*/
|
||||
};
|
||||
|
||||
struct WindowDescription
|
||||
{
|
||||
std::string window_name;
|
||||
@ -54,7 +74,7 @@ struct WindowDescription
|
||||
// then by ORDER BY. This field holds this combined sort order.
|
||||
SortDescription full_sort_description;
|
||||
|
||||
// No frame info as of yet.
|
||||
WindowFrame frame;
|
||||
|
||||
// The window functions that are calculated for this window.
|
||||
std::vector<WindowFunctionDescription> window_functions;
|
||||
|
@ -515,6 +515,20 @@ void makeWindowDescription(WindowDescription & desc, const IAST * ast)
|
||||
desc.full_sort_description = desc.partition_by;
|
||||
desc.full_sort_description.insert(desc.full_sort_description.end(),
|
||||
desc.order_by.begin(), desc.order_by.end());
|
||||
|
||||
if (definition.frame.type != WindowFrame::FrameType::Rows)
|
||||
{
|
||||
std::string name = definition.frame.type == WindowFrame::FrameType::Rows
|
||||
? "ROWS"
|
||||
: definition.frame.type == WindowFrame::FrameType::Groups
|
||||
? "GROUPS" : "RANGE";
|
||||
|
||||
throw Exception(ErrorCodes::NOT_IMPLEMENTED,
|
||||
"Window frame '{}' is not implemented (while processing '{}')",
|
||||
name, ast->formatForErrorMessage());
|
||||
}
|
||||
|
||||
desc.frame = definition.frame;
|
||||
}
|
||||
|
||||
void ExpressionAnalyzer::makeWindowDescriptions(ActionsDAGPtr actions)
|
||||
|
@ -22,6 +22,8 @@ ASTPtr ASTWindowDefinition::clone() const
|
||||
result->children.push_back(result->order_by);
|
||||
}
|
||||
|
||||
result->frame = frame;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
@ -31,12 +33,12 @@ String ASTWindowDefinition::getID(char) const
|
||||
}
|
||||
|
||||
void ASTWindowDefinition::formatImpl(const FormatSettings & settings,
|
||||
FormatState & state, FormatStateStacked frame) const
|
||||
FormatState & state, FormatStateStacked format_frame) const
|
||||
{
|
||||
if (partition_by)
|
||||
{
|
||||
settings.ostr << "PARTITION BY ";
|
||||
partition_by->formatImpl(settings, state, frame);
|
||||
partition_by->formatImpl(settings, state, format_frame);
|
||||
}
|
||||
|
||||
if (partition_by && order_by)
|
||||
@ -47,7 +49,16 @@ void ASTWindowDefinition::formatImpl(const FormatSettings & settings,
|
||||
if (order_by)
|
||||
{
|
||||
settings.ostr << "ORDER BY ";
|
||||
order_by->formatImpl(settings, state, frame);
|
||||
order_by->formatImpl(settings, state, format_frame);
|
||||
}
|
||||
|
||||
if (!frame.is_default)
|
||||
{
|
||||
const auto name = frame.type == WindowFrame::FrameType::Rows
|
||||
? "ROWS" : frame.type == WindowFrame::FrameType::Groups
|
||||
? "GROUPS" : "RANGE";
|
||||
|
||||
settings.ostr << name << " BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW";
|
||||
}
|
||||
}
|
||||
|
||||
@ -56,8 +67,8 @@ std::string ASTWindowDefinition::getDefaultWindowName() const
|
||||
WriteBufferFromOwnString ostr;
|
||||
FormatSettings settings{ostr, true /* one_line */};
|
||||
FormatState state;
|
||||
FormatStateStacked frame;
|
||||
formatImpl(settings, state, frame);
|
||||
FormatStateStacked format_frame;
|
||||
formatImpl(settings, state, format_frame);
|
||||
return ostr.str();
|
||||
}
|
||||
|
||||
|
@ -1,5 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
#include <Interpreters/AggregateDescription.h>
|
||||
|
||||
#include <Parsers/IAST.h>
|
||||
|
||||
|
||||
@ -12,6 +14,8 @@ struct ASTWindowDefinition : public IAST
|
||||
|
||||
ASTPtr order_by;
|
||||
|
||||
WindowFrame frame;
|
||||
|
||||
|
||||
ASTPtr clone() const override;
|
||||
|
||||
|
@ -504,6 +504,65 @@ bool ParserWindowReference::parseImpl(Pos & pos, ASTPtr & node, Expected & expec
|
||||
return parser_definition.parse(pos, function->window_definition, expected);
|
||||
}
|
||||
|
||||
static bool tryParseFrameDefinition(ASTWindowDefinition * node, IParser::Pos & pos,
|
||||
Expected & expected)
|
||||
{
|
||||
ParserKeyword keyword_rows("ROWS");
|
||||
ParserKeyword keyword_groups("GROUPS");
|
||||
ParserKeyword keyword_range("RANGE");
|
||||
|
||||
if (keyword_rows.ignore(pos, expected))
|
||||
{
|
||||
node->frame.type = WindowFrame::FrameType::Rows;
|
||||
}
|
||||
else if (keyword_groups.ignore(pos, expected))
|
||||
{
|
||||
node->frame.type = WindowFrame::FrameType::Groups;
|
||||
}
|
||||
else if (keyword_range.ignore(pos, expected))
|
||||
{
|
||||
node->frame.type = WindowFrame::FrameType::Range;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* No frame clause. */
|
||||
return true;
|
||||
}
|
||||
|
||||
ParserKeyword keyword_between("BETWEEN");
|
||||
ParserKeyword keyword_unbounded("UNBOUNDED");
|
||||
ParserKeyword keyword_preceding("PRECEDING");
|
||||
ParserKeyword keyword_and("AND");
|
||||
ParserKeyword keyword_current_row("CURRENT ROW");
|
||||
|
||||
if (!keyword_between.ignore(pos, expected))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!keyword_unbounded.ignore(pos, expected))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!keyword_preceding.ignore(pos, expected))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!keyword_and.ignore(pos, expected))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!keyword_current_row.ignore(pos, expected))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ParserWindowDefinition::parseImpl(Pos & pos, ASTPtr & node, Expected & expected)
|
||||
{
|
||||
auto result = std::make_shared<ASTWindowDefinition>();
|
||||
@ -548,6 +607,12 @@ bool ParserWindowDefinition::parseImpl(Pos & pos, ASTPtr & node, Expected & expe
|
||||
}
|
||||
}
|
||||
|
||||
if (!tryParseFrameDefinition(result.get(), pos, expected))
|
||||
{
|
||||
/* Broken frame definition. */
|
||||
return false;
|
||||
}
|
||||
|
||||
ParserToken parser_closing_bracket(TokenType::ClosingRoundBracket);
|
||||
if (!parser_closing_bracket.ignore(pos, expected))
|
||||
{
|
||||
|
@ -92,3 +92,15 @@ from numbers(10)
|
||||
window
|
||||
w1 as (partition by intDiv(number, 3))
|
||||
;
|
||||
|
||||
-- ROWS frame
|
||||
select
|
||||
sum(number)
|
||||
over (order by number rows between unbounded preceding and current row)
|
||||
from numbers(3);
|
||||
|
||||
|
||||
select
|
||||
sum(number)
|
||||
over (order by number groups between unbounded preceding and current row)
|
||||
from numbers(3);
|
||||
|
Loading…
Reference in New Issue
Block a user