Skip to content

Commit

Permalink
[Snowflake]Improvement DYNAMIC TABLE (#4193)
Browse files Browse the repository at this point in the history
* Impr CREATE

* Improv ALTER DYNAMIC TABLE

* Refacto RLS for table

* Formatting

* Format again

* Fix NULL_IF could have a null list in file format

* Add LAG as undocumented keyword for DYNAMIC TABLE

* Add any order for dynamic table params and some keyword exclusion

* Fix format
  • Loading branch information
MasterKuat authored Aug 16, 2024
1 parent 0fef40d commit 17bba09
Show file tree
Hide file tree
Showing 4 changed files with 150 additions and 37 deletions.
57 changes: 31 additions & 26 deletions sql/snowflake/SnowflakeLexer.g4
Original file line number Diff line number Diff line change
Expand Up @@ -398,12 +398,12 @@ GROUPS : 'GROUPS';
GZIP : 'GZIP';
HALF_AWAY_FROM_ZERO_Q : '\'HALF_AWAY_FROM_ZERO\'';
HALF_TO_EVEN_Q : '\'HALF_TO_EVEN\'';
HANDLER : 'HANDLER';
HASH : 'HASH';
HAVING : 'HAVING';
HEADER : 'HEADER';
HEADERS : 'HEADERS';
HEX : 'HEX';
HANDLER : 'HANDLER';
HASH : 'HASH';
HAVING : 'HAVING';
HEADER : 'HEADER';
HEADERS : 'HEADERS';
HEX : 'HEX';
// HIERARCHYID: 'HIERARCHYID';
// HIGH: 'HIGH';
HISTORY: 'HISTORY';
Expand All @@ -429,9 +429,11 @@ IMPORTS : 'IMPORTS';
IMPORTED : 'IMPORTED';
IN : 'IN';
INCREMENT : 'INCREMENT';
INCREMENTAL : 'INCREMENTAL';
INDEX : 'INDEX';
INFORMATION : 'INFORMATION';
// INIT: 'INIT';
INITIALIZE : 'INITIALIZE';
INITIALLY : 'INITIALLY';
INITIALLY_SUSPENDED : 'INITIALLY_SUSPENDED';
INITIAL_REPLICATION_SIZE_LIMIT_IN_TB : 'INITIAL_REPLICATION_SIZE_LIMIT_IN_TB';
Expand Down Expand Up @@ -604,8 +606,10 @@ OMIT : 'OMIT';
ON : 'ON';
ONE : 'ONE';
// ONLINE: 'ONLINE';
ONLY : 'ONLY';
ON_ERROR : 'ON_ERROR';
ONLY : 'ONLY';
ON_CREATE : 'ON_CREATE';
ON_ERROR : 'ON_ERROR';
ON_SCHEDULE : 'ON_SCHEDULE';
// ON_FAILURE: 'ON_FAILURE';
// OPEN: 'OPEN';
OPERATE: 'OPERATE';
Expand Down Expand Up @@ -635,24 +639,24 @@ PARQUET_Q : '\'PARQUET\'';
PARTIAL : 'PARTIAL';
PARTITION : 'PARTITION';
// PARTITIONS: 'PARTITIONS';
PARTITION_TYPE : 'PARTITION_TYPE';
PASSWORD : 'PASSWORD';
PASSWORD_HISTORY : 'PASSWORD_HISTORY';
PASSWORD_LOCKOUT_TIME_MINS : 'PASSWORD_LOCKOUT_TIME_MINS';
PASSWORD_MAX_AGE_DAYS : 'PASSWORD_MAX_AGE_DAYS';
PASSWORD_MAX_LENGTH : 'PASSWORD_MAX_LENGTH';
PASSWORD_MAX_RETRIES : 'PASSWORD_MAX_RETRIES';
PASSWORD_MIN_AGE_DAYS : 'PASSWORD_MIN_AGE_DAYS';
PASSWORD_MIN_LENGTH : 'PASSWORD_MIN_LENGTH';
PASSWORD_MIN_LOWER_CASE_CHARS : 'PASSWORD_MIN_LOWER_CASE_CHARS';
PASSWORD_MIN_NUMERIC_CHARS : 'PASSWORD_MIN_NUMERIC_CHARS';
PASSWORD_MIN_SPECIAL_CHARS : 'PASSWORD_MIN_SPECIAL_CHARS';
PASSWORD_MIN_UPPER_CASE_CHARS : 'PASSWORD_MIN_UPPER_CASE_CHARS';
PAST : 'PAST';
PATH_ : 'PATH';
PATTERN : 'PATTERN';
PER : 'PER';
PERCENT : 'PERCENT';
PARTITION_TYPE : 'PARTITION_TYPE';
PASSWORD : 'PASSWORD';
PASSWORD_HISTORY : 'PASSWORD_HISTORY';
PASSWORD_LOCKOUT_TIME_MINS : 'PASSWORD_LOCKOUT_TIME_MINS';
PASSWORD_MAX_AGE_DAYS : 'PASSWORD_MAX_AGE_DAYS';
PASSWORD_MAX_LENGTH : 'PASSWORD_MAX_LENGTH';
PASSWORD_MAX_RETRIES : 'PASSWORD_MAX_RETRIES';
PASSWORD_MIN_AGE_DAYS : 'PASSWORD_MIN_AGE_DAYS';
PASSWORD_MIN_LENGTH : 'PASSWORD_MIN_LENGTH';
PASSWORD_MIN_LOWER_CASE_CHARS : 'PASSWORD_MIN_LOWER_CASE_CHARS';
PASSWORD_MIN_NUMERIC_CHARS : 'PASSWORD_MIN_NUMERIC_CHARS';
PASSWORD_MIN_SPECIAL_CHARS : 'PASSWORD_MIN_SPECIAL_CHARS';
PASSWORD_MIN_UPPER_CASE_CHARS : 'PASSWORD_MIN_UPPER_CASE_CHARS';
PAST : 'PAST';
PATH_ : 'PATH';
PATTERN : 'PATTERN';
PER : 'PER';
PERCENT : 'PERCENT';
// PERCENTILE_CONT: 'PERCENTILE_CONT';
// PERCENTILE_DISC: 'PERCENTILE_DISC';
// PERCENT_RANK: 'PERCENT_RANK';
Expand Down Expand Up @@ -731,6 +735,7 @@ RECURSIVE: 'RECURSIVE';
REFERENCES : 'REFERENCES';
REFERENCE_USAGE : 'REFERENCE_USAGE';
REFRESH : 'REFRESH';
REFRESH_MODE : 'REFRESH_MODE';
REFRESH_ON_CREATE : 'REFRESH_ON_CREATE';
REGION : 'REGION';
REGIONS : 'REGIONS';
Expand Down
96 changes: 85 additions & 11 deletions sql/snowflake/SnowflakeParser.g4
Original file line number Diff line number Diff line change
Expand Up @@ -752,7 +752,18 @@ account_id_list
;

alter_dynamic_table
: ALTER DYNAMIC TABLE id_ (resume_suspend | REFRESH | SET WAREHOUSE EQ id_)
: ALTER DYNAMIC TABLE if_exists? object_name (
resume_suspend
| REFRESH
| SET dynamic_table_settable_params+
)
| ALTER DYNAMIC TABLE if_exists? object_name (SWAP WITH | RENAME TO) object_name
| ALTER DYNAMIC TABLE if_exists? object_name (set_tags | unset_tags)
| ALTER DYNAMIC TABLE if_exists? object_name search_optimization_action
| ALTER DYNAMIC TABLE if_exists? object_name UNSET dynamic_table_unsettable_params (
COMMA dynamic_table_unsettable_params
)*
| ALTER DYNAMIC TABLE if_exists? object_name rls_operations
;

alter_external_table
Expand Down Expand Up @@ -1149,10 +1160,15 @@ alter_table
|
)
//[ , ... ]
| ALTER TABLE if_exists? object_name ADD ROW ACCESS POLICY id_ ON column_list_in_parentheses
| ALTER TABLE if_exists? object_name DROP ROW ACCESS POLICY id_
| ALTER TABLE if_exists? object_name DROP ROW ACCESS POLICY id_ COMMA ADD ROW ACCESS POLICY id_ ON column_list_in_parentheses
| ALTER TABLE if_exists? object_name DROP ALL ROW ACCESS POLICIES
| ALTER TABLE if_exists? object_name rls_operations
;

rls_operations
: ADD ROW ACCESS POLICY object_name ON column_list_in_parentheses
| DROP ROW ACCESS POLICY object_name (
COMMA ADD ROW ACCESS POLICY object_name ON column_list_in_parentheses
)?
| DROP ALL ROW ACCESS POLICIES
;

clustering_action
Expand Down Expand Up @@ -1568,13 +1584,49 @@ compression
;

create_dynamic_table
: CREATE or_replace? DYNAMIC TABLE id_ TARGET_LAG EQ (string | DOWNSTREAM) WAREHOUSE EQ wh = id_ AS query_statement
: CREATE or_replace? TRANSIENT? DYNAMIC TABLE if_not_exists? object_name (
LR_BRACKET materialized_col_decl_list RR_BRACKET
)? dynamic_table_params+ AS query_statement
;

dynamic_table_params
: dynamic_table_settable_params
| REFRESH_MODE EQ (AUTO | FULL | INCREMENTAL)
| INITIALIZE EQ (ON_CREATE | ON_SCHEDULE)
| cluster_by
| with_row_access_policy
| with_tags
;

dynamic_table_settable_params
: TARGET_LAG EQ (string | DOWNSTREAM)
| LAG EQ (
string
| DOWNSTREAM
) // LAG is same as TARGET_LAG but not in documentation. BTW GET_DLL return LAG keyword and not TARGET_LAG
| WAREHOUSE EQ wh = id_
| set_data_retention_params
| DEFAULT_DDL_COLLATION_ EQ STRING
| comment_clause
;

dynamic_table_unsettable_params
: data_retention_params
| DEFAULT_DDL_COLLATION_
| COMMENT
;

data_retention_params
: DATA_RETENTION_TIME_IN_DAYS
| MAX_DATA_EXTENSION_TIME_IN_DAYS
;

set_data_retention_params
: data_retention_params EQ num
;

create_event_table
: CREATE or_replace? EVENT TABLE if_not_exists? id_ cluster_by? (
DATA_RETENTION_TIME_IN_DAYS EQ num
)? (MAX_DATA_EXTENSION_TIME_IN_DAYS EQ num)? change_tracking? (
: CREATE or_replace? EVENT TABLE if_not_exists? id_ cluster_by? data_retention_params* change_tracking? (
DEFAULT_DDL_COLLATION_ EQ string
)? copy_grants? with_row_access_policy? with_tags? (WITH? comment_clause)?
;
Expand Down Expand Up @@ -2005,7 +2057,7 @@ format_type_options
| ESCAPE_UNENCLOSED_FIELD EQ (string | NONE | NONE_Q)
| TRIM_SPACE EQ true_false
| FIELD_OPTIONALLY_ENCLOSED_BY EQ (string | NONE | NONE_Q | SINGLE_QUOTE)
| NULL_IF EQ LR_BRACKET string_list RR_BRACKET
| NULL_IF EQ LR_BRACKET string_list* RR_BRACKET
| ERROR_ON_COLUMN_COUNT_MISMATCH EQ true_false
| REPLACE_INVALID_CHARACTERS EQ true_false
| EMPTY_FIELD_AS_NULL EQ true_false
Expand Down Expand Up @@ -2367,12 +2419,22 @@ out_of_line_constraint
)
;

//For classic table
full_col_decl
: col_decl (collate | inline_constraint | null_not_null | (default_value | NULL_))* with_masking_policy? with_tags? (
COMMENT string
)?
;

//Column declaration for materialized table
materialized_col_decl
: column_name data_type? with_masking_policy? with_tags? (COMMENT string)?
;

materialized_col_decl_list
: materialized_col_decl (COMMA materialized_col_decl)*
;

column_decl_item
: full_col_decl
| out_of_line_constraint
Expand Down Expand Up @@ -3507,6 +3569,7 @@ keyword
| IF
| JOIN
| KEY
| LAG
| LANGUAGE
| LENGTH
| MAX_CONCURRENCY_LEVEL
Expand Down Expand Up @@ -3550,16 +3613,21 @@ non_reserved_words
| DOWNSTREAM
| DYNAMIC
| EDITION
| ENABLED
| EMAIL
| EMPTY_
| EVENT
| EXCHANGE
| EXPIRY_DATE
| EXPR
| FIRST_NAME
| FIRST_VALUE
| GLOBAL
| IDENTIFIER
| IDENTITY
| INCREMENTAL
| INDEX
| INITIALIZE
| INPUT
| INTERVAL
| JAVASCRIPT
Expand All @@ -3570,6 +3638,9 @@ non_reserved_words
| NAME
| NETWORK
| OFFSET
| ON_CREATE
| ON_ERROR
| ON_SCHEDULE
| OPTION
| ORGADMIN
| OUTBOUND
Expand All @@ -3594,6 +3665,7 @@ non_reserved_words
| PROVIDER
| PUBLIC
| RANK
| REFRESH_MODE
| RESOURCE
| RESOURCES
| RESPECT
Expand Down Expand Up @@ -4357,6 +4429,8 @@ round_mode
;

round_expr
: ROUND LR_BRACKET EXPR ASSOC expr COMMA SCALE ASSOC expr (COMMA ROUNDING_MODE ASSOC round_mode)* RR_BRACKET
: ROUND LR_BRACKET EXPR ASSOC expr COMMA SCALE ASSOC expr (
COMMA ROUNDING_MODE ASSOC round_mode
)* RR_BRACKET
| ROUND LR_BRACKET expr COMMA expr (COMMA round_mode)* RR_BRACKET
;
31 changes: 31 additions & 0 deletions sql/snowflake/examples/dynamic_table.sql
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,13 @@ alter dynamic table dt1 suspend;
alter dynamic table dt1 refresh;
alter dynamic table dt1 set warehouse = wh2;
alter dynamic table dt1 resume;
ALTER DYNAMIC TABLE dt1 SET TARGET_LAG = DOWNSTREAM WAREHOUSE = wh1 MAX_DATA_EXTENSION_TIME_IN_DAYS = 2;
ALTER DYNAMIC TABLE dt1 UNSET DATA_RETENTION_TIME_IN_DAYS, MAX_DATA_EXTENSION_TIME_IN_DAYS, COMMENT;
alter dynamic table dt1 SWAP WITH DT2;
alter dynamic table dt1 rename to DT2;
ALTER DYNAMIC TABLE DT1 DROP ROW ACCESS POLICY PUBLIC.RLS_STRING;
ALTER DYNAMIC TABLE DT1 ADD ROW ACCESS POLICY PUBLIC.RLS_STRING ON (C1);
ALTER DYNAMIC TABLE DT1 DROP ROW ACCESS POLICY PUBLIC.RLS_STRING , ADD ROW ACCESS POLICY PUBLIC.RLS_STRING ON (C1);

describe dynamic table dt1;

Expand All @@ -15,3 +22,27 @@ show dynamic tables like 'dt%';
show dynamic tables in account;

drop dynamic table dt1;

create dynamic table dt1 (c1 int WITH MASKING POLICY mpol TAG ( T = 'mytag'))
target_lag = downstream
warehouse = wh1
as select 1;

create transient dynamic table dt1 (c1)
warehouse = wh1
DATA_RETENTION_TIME_IN_DAYS = 1
target_lag = downstream
as select 1;

create dynamic table dt1 (c1 int WITH MASKING POLICY mpol TAG ( T = 'mytag') COMMENT 'com')
target_lag = '1 days'
warehouse = wh1
DATA_RETENTION_TIME_IN_DAYS = 1
MAX_DATA_EXTENSION_TIME_IN_DAYS = 1
COMMENT = 'Table Com'
REFRESH_MODE = AUTO
INITIALIZE = ON_SCHEDULE
CLUSTER BY (C1)
WITH ROW ACCESS POLICY RLS ON ( C1 )
WITH TAG ( T2 = 'ValT2')
as select 1;
3 changes: 3 additions & 0 deletions sql/snowflake/examples/tables.sql
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,6 @@ create table t(i int);

alter table t add column if not exists j int;
alter table t drop column if exists i;
ALTER TABLE t ADD ROW ACCESS POLICY RLS ON (j);
ALTER TABLE t DROP ROW ACCESS POLICY RLS;
ALTER TABLE t DROP ROW ACCESS POLICY RLS , ADD ROW ACCESS POLICY RLS ON (j);

0 comments on commit 17bba09

Please sign in to comment.