Skip to content

Commit

Permalink
Merge pull request #10 from jingchen2222/feat/exclude_current_time
Browse files Browse the repository at this point in the history
feat: support instance_not_in_window and exclude current_time
  • Loading branch information
jingchen2222 authored May 25, 2021
2 parents 33bab5b + 9034897 commit c8f1d46
Show file tree
Hide file tree
Showing 8 changed files with 126 additions and 6 deletions.
33 changes: 28 additions & 5 deletions zetasql/parser/bison_parser.y
Original file line number Diff line number Diff line change
Expand Up @@ -697,6 +697,7 @@ using zetasql::ASTDropStatement;
%token KW_IGNORE "IGNORE"
%token KW_IN "IN"
%token KW_INNER "INNER"
%token KW_INSTANCE_NOT_IN_WINDOW "INSTANCE_NOT_IN_WINDOW"
%token KW_INTERSECT "INTERSECT"
%token KW_INTERVAL "INTERVAL"
%token KW_INTO "INTO"
Expand Down Expand Up @@ -797,6 +798,7 @@ using zetasql::ASTDropStatement;
%token KW_CONTINUE "CONTINUE"
%token KW_CONSTANT "CONSTANT"
%token KW_CONSTRAINT "CONSTRAINT"
%token KW_CURRENT_TIME "CURRENT_TIME"
%token KW_DATA "DATA"
%token KW_DATABASE "DATABASE"
%token KW_DATE "DATE"
Expand Down Expand Up @@ -1366,6 +1368,8 @@ using zetasql::ASTDropStatement;
%type <boolean> opt_recursive
%type <boolean> opt_unique
%type <boolean> opt_search
%type <boolean> opt_instance_not_in_window
%type <boolean> opt_exclude_current_time
%type <node> opt_with_anonymization
%type <node> primary_key_column_attribute
%type <node> hidden_column_attribute
Expand Down Expand Up @@ -6598,7 +6602,7 @@ frame_unit:
;

opt_window_frame_clause:
frame_unit "BETWEEN" window_frame_bound "AND for BETWEEN" window_frame_bound opt_maxsize
frame_unit "BETWEEN" window_frame_bound "AND for BETWEEN" window_frame_bound opt_maxsize
{
auto* frame = MAKE_NODE(ASTWindowFrame, @$, {$3, $5, $6});
frame->set_unit($1);
Expand All @@ -6611,23 +6615,40 @@ opt_window_frame_clause:
$$ = frame;
}
| /* Nothing */ { $$ = nullptr; }

;
opt_maxsize:
"MAXSIZE" integer_literal
{
$$ = MAKE_NODE(ASTMaxSize, @$, {$2});
}
| /* Nothing */ { $$ = nullptr; }

;
opt_instance_not_in_window:
"INSTANCE_NOT_IN_WINDOW"
{
$$ = true;
};
| /* Nothing */ { $$ = false; }
;
opt_exclude_current_time:
"EXCLUDE" "CURRENT_TIME"
{
$$ = true;
};
| /* Nothing */ { $$ = false; }
;
window_specification:
identifier
{
$$ = MAKE_NODE(ASTWindowSpecification, @$, {$1});
}
| "(" opt_identifier opt_partition_by_clause opt_order_by_clause
opt_window_frame_clause ")"
opt_window_frame_clause opt_exclude_current_time opt_instance_not_in_window ")"
{
$$ = MAKE_NODE(ASTWindowSpecification, @$, {$2, $3, $4, $5});
auto *window_spec = MAKE_NODE(ASTWindowSpecification, @$, {$2, $3, $4, $5});
window_spec->set_is_exclude_current_time($6);
window_spec->set_is_instance_not_in_window($7);
$$ = window_spec;
}
;

Expand Down Expand Up @@ -7009,6 +7030,7 @@ reserved_keyword_rule:
| "IGNORE"
| "IN"
| "INNER"
| "INSTANCE_NOT_IN_WINDOW"
| "INTERSECT"
| "INTERVAL"
| "INTO"
Expand Down Expand Up @@ -7104,6 +7126,7 @@ keyword_as_identifier:
| "CONSTANT"
| "CONSTRAINT"
| "CONTINUE"
| "CURRENT_TIME"
| "DATA"
| "DATABASE"
| "DATE"
Expand Down
2 changes: 2 additions & 0 deletions zetasql/parser/flex_tokenizer.l
Original file line number Diff line number Diff line change
Expand Up @@ -399,6 +399,7 @@ create { return BisonParserImpl::token::KW_CREATE; }
cross { return BisonParserImpl::token::KW_CROSS; }
cube { return BisonParserImpl::token::KW_CUBE; }
current { return BisonParserImpl::token::KW_CURRENT; }
current_time { return BisonParserImpl::token::KW_CURRENT_TIME;}
data { return BisonParserImpl::token::KW_DATA; }
database { return BisonParserImpl::token::KW_DATABASE; }
date { return BisonParserImpl::token::KW_DATE; }
Expand Down Expand Up @@ -480,6 +481,7 @@ include { return BisonParserImpl::token::KW_INCLUDE; }
inout { return BisonParserImpl::token::KW_INOUT; }
index { return BisonParserImpl::token::KW_INDEX; }
inner { return BisonParserImpl::token::KW_INNER; }
instance_not_in_window { return BisonParserImpl::token::KW_INSTANCE_NOT_IN_WINDOW; }
insert { return BisonParserImpl::token::KW_INSERT; }
intersect { return BisonParserImpl::token::KW_INTERSECT; }
interval { return BisonParserImpl::token::KW_INTERVAL; }
Expand Down
2 changes: 2 additions & 0 deletions zetasql/parser/keywords.cc
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,7 @@ constexpr KeywordInfoPOD kAllKeywords[] = {
{"cross", KW_CROSS, KeywordInfo::kReserved},
{"cube", KW_CUBE, KeywordInfo::kReserved},
{"current", KW_CURRENT, KeywordInfo::kReserved},
{"current_time", KW_CURRENT_TIME},
{"data", KW_DATA},
{"database", KW_DATABASE},
{"date", KW_DATE},
Expand Down Expand Up @@ -160,6 +161,7 @@ constexpr KeywordInfoPOD kAllKeywords[] = {
{"index", KW_INDEX},
{"inner", KW_INNER, KeywordInfo::kReserved},
{"insert", KW_INSERT},
{"instance_not_in_window", KW_INSTANCE_NOT_IN_WINDOW, KeywordInfo::kReserved},
{"intersect", KW_INTERSECT, KeywordInfo::kReserved},
{"interval", KW_INTERVAL, KeywordInfo::kReserved},
{"iterate", KW_ITERATE},
Expand Down
2 changes: 1 addition & 1 deletion zetasql/parser/keywords_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -237,7 +237,7 @@ TEST(ParserTest, DontAddNewReservedKeywords) {
// allows new queries to work that will not work on older code.
// Before changing this, co-ordinate with all engines to make sure the change
// is done safely.
EXPECT_EQ(96 /* CAUTION */, num_reserved);
EXPECT_EQ(97 /* CAUTION */, num_reserved);
}

} // namespace
Expand Down
15 changes: 15 additions & 0 deletions zetasql/parser/parse_tree.cc
Original file line number Diff line number Diff line change
Expand Up @@ -906,6 +906,21 @@ std::string ASTWindowFrame::SingleNodeDebugString() const {
return absl::StrCat(ASTNode::SingleNodeDebugString(), "(",
GetFrameUnitString(), ")");
}
std::string ASTWindowSpecification::SingleNodeDebugString() const {
if (is_instance_not_in_window_ && is_exclude_current_time_) {
return absl::StrCat(ASTNode::SingleNodeDebugString(),
"(is_exclude_current_time, is_instance_not_in_window)");
}
if (is_instance_not_in_window_) {
return absl::StrCat(ASTNode::SingleNodeDebugString(),
"(is_instance_not_in_window)");
}
if (is_exclude_current_time_) {
return absl::StrCat(ASTNode::SingleNodeDebugString(),
"(is_exclude_current_time)");
}
return ASTNode::SingleNodeDebugString();
}

// static
std::string ASTWindowFrame::FrameUnitToString(FrameUnit unit) {
Expand Down
9 changes: 9 additions & 0 deletions zetasql/parser/parse_tree_manual.h
Original file line number Diff line number Diff line change
Expand Up @@ -2817,7 +2817,13 @@ class ASTWindowSpecification final : public ASTNode {
const ASTWindowFrame* window_frame() const { return window_frame_; }

const ASTIdentifier* base_window_name() const { return base_window_name_; }

bool is_instance_not_in_window() const { return is_instance_not_in_window_; }
void set_is_instance_not_in_window(bool value) { is_instance_not_in_window_ = value; }

bool is_exclude_current_time() const { return is_exclude_current_time_; }
void set_is_exclude_current_time(bool value) { is_exclude_current_time_ = value; }
std::string SingleNodeDebugString() const override;
private:
void InitFields() final {
FieldLoader fl(this);
Expand All @@ -2832,6 +2838,9 @@ class ASTWindowSpecification final : public ASTNode {
const ASTPartitionBy* partition_by_ = nullptr;
const ASTOrderBy* order_by_ = nullptr;
const ASTWindowFrame* window_frame_ = nullptr;

bool is_instance_not_in_window_ = false;
bool is_exclude_current_time_ = false;
};

class ASTWindowDefinition final : public ASTNode {
Expand Down
62 changes: 62 additions & 0 deletions zetasql/parser/testdata/analytic_functions.test
Original file line number Diff line number Diff line change
Expand Up @@ -655,6 +655,68 @@ FROM
T
==

# window with exclude current_time
select f() over (rows_range between 5s preceding and current row maxsize 5 exclude current_time)
from T
--
QueryStatement [0-103]
Query [0-103]
Select [0-103]
SelectList [7-96]
SelectColumn [7-96]
AnalyticFunctionCall [7-96]
FunctionCall [7-10]
PathExpression [7-8]
Identifier(f) [7-8]
WindowSpecification(is_exclude_current_time) [16-96]
WindowFrame(ROWS_RANGE) [17-74]
WindowFrameExpr(OFFSET PRECEDING) [36-48]
IntervalLiteral(5s) [36-38]
WindowFrameExpr(CURRENT ROW) [53-64]
MaxSize [65-74]
IntLiteral(5) [73-74]
FromClause [97-103]
TablePathExpression [102-103]
PathExpression [102-103]
Identifier(T) [102-103]
--
SELECT
f() OVER (ROWS_RANGE BETWEEN 5s PRECEDING AND CURRENT ROW MAXSIZE 5 EXCLUDE CURRENT_TIME)
FROM
T
==

# window with instance_not_in_window
select f() over (rows_range between 5s preceding and current row maxsize 5 instance_not_in_window)
from T
--
QueryStatement [0-105]
Query [0-105]
Select [0-105]
SelectList [7-98]
SelectColumn [7-98]
AnalyticFunctionCall [7-98]
FunctionCall [7-10]
PathExpression [7-8]
Identifier(f) [7-8]
WindowSpecification(is_instance_not_in_window) [16-98]
WindowFrame(ROWS_RANGE) [17-74]
WindowFrameExpr(OFFSET PRECEDING) [36-48]
IntervalLiteral(5s) [36-38]
WindowFrameExpr(CURRENT ROW) [53-64]
MaxSize [65-74]
IntLiteral(5) [73-74]
FromClause [99-105]
TablePathExpression [104-105]
PathExpression [104-105]
Identifier(T) [104-105]
--
SELECT
f() OVER (ROWS_RANGE BETWEEN 5s PRECEDING AND CURRENT ROW MAXSIZE 5 INSTANCE_NOT_IN_WINDOW)
FROM
T
==

select f() over (range between 5+5 preceding and current {{rows|blah}})
from T
--
Expand Down
7 changes: 7 additions & 0 deletions zetasql/parser/unparser.cc
Original file line number Diff line number Diff line change
Expand Up @@ -2111,6 +2111,13 @@ void Unparser::visitASTWindowDefinition(
void Unparser::visitASTWindowSpecification(
const ASTWindowSpecification* node, void* data) {
UnparseChildrenWithSeparator(node, data, "");
if (node->is_exclude_current_time()) {
print("EXCLUDE CURRENT_TIME");
}

if (node->is_instance_not_in_window()) {
print("INSTANCE_NOT_IN_WINDOW");
}
}

void Unparser::visitASTPartitionBy(const ASTPartitionBy* node, void* data) {
Expand Down

0 comments on commit c8f1d46

Please sign in to comment.