Skip to content

Commit

Permalink
Snowflake: Add implementation for CREATE TASK statement (sqlfluff#1597)
Browse files Browse the repository at this point in the history
  • Loading branch information
Joe Hutter committed Oct 12, 2021
1 parent e02da76 commit 372abe7
Show file tree
Hide file tree
Showing 7 changed files with 251 additions and 1 deletion.
102 changes: 101 additions & 1 deletion src/sqlfluff/dialects/dialect_snowflake.py
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,8 @@
"TERSE",
"TABULAR",
"UNSET",
"USER_TASK_TIMEOUT_MS",
"USER_TASK_MANAGED_INITIAL_WAREHOUSE_SIZE",
"WAIT_FOR_COMPLETION",
"WAREHOUSE_SIZE",
]
Expand Down Expand Up @@ -436,6 +438,7 @@ class StatementSegment(ansi_dialect.get_segment("StatementSegment")): # type: i
insert=[
Ref("UseStatementSegment"),
Ref("CreateStatementSegment"),
Ref("CreateTaskSegment"),
Ref("CreateCloneStatementSegment"),
Ref("ShowStatementSegment"),
Ref("AlterUserSegment"),
Expand Down Expand Up @@ -1341,6 +1344,104 @@ class CreateTableStatementSegment(BaseSegment):
)


@snowflake_dialect.segment()
class CreateTaskSegment(BaseSegment):
"""A snowflake `CREATE TASK` statement.
```
CREATE [ OR REPLACE ] TASK [ IF NOT EXISTS ] <name>
[ WAREHOUSE = <string> ]
[ SCHEDULE = '{ <num> MINUTE | USING CRON <expr> <time_zone> }' ]
[ ALLOW_OVERLAPPING_EXECUTION = TRUE | FALSE ]
[ <session_parameter> = <value> [ , <session_parameter> = <value> ... ] ]
[ USER_TASK_TIMEOUT_MS = <num> ]
[ USER_TASK_MANAGED_INITIAL_WAREHOUSE_SIZE = <string> ]
[ COPY GRANTS ]
[ COMMENT = '<string_literal>' ]
[ AFTER <string> ]
[ WHEN <boolean_expr> ]
AS
<sql>
```
CAUTION: The `WHEN` clause is currently not implemented.
https://docs.snowflake.com/en/sql-reference/sql/create-task.html
"""

type = "create_task_statement"

match_grammar = Sequence(
"CREATE",
Sequence("OR", "REPLACE", optional=True),
"TASK",
Sequence("IF", "NOT", "EXISTS", optional=True),
Ref("ObjectReferenceSegment"),
Indent,
Sequence(
"WAREHOUSE",
Ref("EqualsSegment"),
Ref("ObjectReferenceSegment"),
optional=True,
),
Sequence(
"SCHEDULE",
Ref("EqualsSegment"),
Ref("QuotedLiteralSegment"),
optional=True,
),
Sequence(
"ALLOW_OVERLAPPING_EXECUTION",
Ref("EqualsSegment"),
Ref("BooleanLiteralGrammar"),
optional=True,
),
Delimited(
Sequence(
Ref("ParameterNameSegment"),
Ref("EqualsSegment"),
OneOf(
Ref("BooleanLiteralGrammar"),
Ref("QuotedLiteralSegment"),
Ref("NumericLiteralSegment"),
),
),
delimiter=Ref("CommaSegment"),
optional=True
),
Sequence(
"USER_TASK_TIMEOUT_MS",
Ref("EqualsSegment"),
Ref("NumericLiteralSegment"),
optional=True,
),
Sequence(
"USER_TASK_MANAGED_INITIAL_WAREHOUSE_SIZE",
Ref("EqualsSegment"),
Ref("QuotedLiteralSegment"),
optional=True,
),
Sequence(
"COPY",
"GRANTS",
optional=True,
),
Ref("CreateStatementCommentSegment", optional=True),
Sequence(
"AFTER",
Ref("QuotedLiteralSegment"),
optional=True,
),
Dedent,
Sequence(
Ref.keyword("AS"),
Indent,
Ref("StatementSegment"),
Dedent,
),
)


@snowflake_dialect.segment()
class CreateStatementSegment(BaseSegment):
"""A snowflake `CREATE` statement.
Expand Down Expand Up @@ -1378,7 +1479,6 @@ class CreateStatementSegment(BaseSegment):
Sequence("FILE", "FORMAT"),
"STAGE",
"STREAM",
"TASK",
),
Sequence("IF", "NOT", "EXISTS", optional=True),
Ref("ObjectReferenceSegment"),
Expand Down
6 changes: 6 additions & 0 deletions test/fixtures/parser/snowflake/snowflake_create_task.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
CREATE TASK t1
SCHEDULE = 'USING CRON 0 9-17 * * SUN America/Los_Angeles'
TIMESTAMP_INPUT_FORMAT = 'YYYY-MM-DD HH24'
USER_TASK_MANAGED_INITIAL_WAREHOUSE_SIZE = 'XSMALL'
AS
INSERT INTO mytable(ts) VALUES(1);
41 changes: 41 additions & 0 deletions test/fixtures/parser/snowflake/snowflake_create_task.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
# YML test files are auto-generated from SQL files and should not be edited by
# hand. To help enforce this, the "hash" field in the file must match a hash
# computed by SQLFluff when running the tests. Please run
# `python test/generate_parse_fixture_yml.py` to generate them after adding or
# altering SQL files.
_hash: af2323a0483bae83a81490bc28c4d8acd8b0c793aaa661b9dc0ed6d2d85fa7de
file:
statement:
create_task_statement:
- keyword: CREATE
- keyword: TASK
- object_reference:
identifier: t1
- keyword: SCHEDULE
- comparison_operator: '='
- literal: "'USING CRON 0 9-17 * * SUN America/Los_Angeles'"
- parameter: TIMESTAMP_INPUT_FORMAT
- comparison_operator: '='
- literal: "'YYYY-MM-DD HH24'"
- keyword: USER_TASK_MANAGED_INITIAL_WAREHOUSE_SIZE
- comparison_operator: '='
- literal: "'XSMALL'"
- keyword: AS
- statement:
insert_statement:
- keyword: INSERT
- keyword: INTO
- table_reference:
identifier: mytable
- bracketed:
start_bracket: (
column_reference:
identifier: ts
end_bracket: )
- values_clause:
keyword: VALUES
bracketed:
start_bracket: (
literal: '1'
end_bracket: )
statement_terminator: ;
12 changes: 12 additions & 0 deletions test/fixtures/parser/snowflake/snowflake_create_task_all.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
CREATE OR REPLACE TASK IF NOT EXISTS t1
WAREHOUSE = mywh
SCHEDULE = 'USING CRON 0 9-17 * * SUN America/Los_Angeles'
ALLOW_OVERLAPPING_EXECUTION = TRUE
TIMESTAMP_INPUT_FORMAT = 'YYYY-MM-DD HH24'
USER_TASK_TIMEOUT_MS = 25
USER_TASK_MANAGED_INITIAL_WAREHOUSE_SIZE = 'XSMALL'
COPY GRANTS
COMMENT = 'Hello world'
AFTER 'dependency_task'
AS
INSERT INTO mytable(ts) VALUES(1);
56 changes: 56 additions & 0 deletions test/fixtures/parser/snowflake/snowflake_create_task_all.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
# YML test files are auto-generated from SQL files and should not be edited by
# hand. To help enforce this, the "hash" field in the file must match a hash
# computed by SQLFluff when running the tests. Please run
# `python test/generate_parse_fixture_yml.py` to generate them after adding or
# altering SQL files.
_hash: d7c9c725318a322009d331c30dba49c4ed9483b71e832b04923f79a61bb8d703
file:
statement:
unparsable:
- raw: CREATE
- raw: OR
- raw: REPLACE
- raw: TASK
- raw: IF
- raw: NOT
- raw: EXISTS
- raw: t1
- raw: WAREHOUSE
- raw: '='
- raw: mywh
- raw: SCHEDULE
- raw: '='
- raw: "'USING CRON 0 9-17 * * SUN America/Los_Angeles'"
- raw: ALLOW_OVERLAPPING_EXECUTION
- raw: '='
- raw: 'TRUE'
- raw: TIMESTAMP_INPUT_FORMAT
- raw: '='
- raw: "'YYYY-MM-DD HH24'"
- raw: USER_TASK_TIMEOUT_MS
- raw: '='
- raw: '25'
- raw: USER_TASK_MANAGED_INITIAL_WAREHOUSE_SIZE
- raw: '='
- raw: "'XSMALL'"
- raw: COPY
- raw: GRANTS
- raw: COMMENT
- raw: '='
- raw: "'Hello world'"
- raw: AFTER
- raw: "'dependency_task'"
- raw: AS
- raw: INSERT
- raw: INTO
- raw: mytable
- bracketed:
start_bracket: (
raw: ts
end_bracket: )
- raw: VALUES
- bracketed:
start_bracket: (
raw: '1'
end_bracket: )
statement_terminator: ;
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
CREATE TASK t1
AS
INSERT INTO mytable(ts) VALUES(1);
32 changes: 32 additions & 0 deletions test/fixtures/parser/snowflake/snowflake_create_task_minimal.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
# YML test files are auto-generated from SQL files and should not be edited by
# hand. To help enforce this, the "hash" field in the file must match a hash
# computed by SQLFluff when running the tests. Please run
# `python test/generate_parse_fixture_yml.py` to generate them after adding or
# altering SQL files.
_hash: 5e7d90046023eb14b11e0b6ee84b48e2160de04eae5298e041dbf4de00598a2c
file:
statement:
create_task_statement:
- keyword: CREATE
- keyword: TASK
- object_reference:
identifier: t1
- keyword: AS
- statement:
insert_statement:
- keyword: INSERT
- keyword: INTO
- table_reference:
identifier: mytable
- bracketed:
start_bracket: (
column_reference:
identifier: ts
end_bracket: )
- values_clause:
keyword: VALUES
bracketed:
start_bracket: (
literal: '1'
end_bracket: )
statement_terminator: ;

0 comments on commit 372abe7

Please sign in to comment.