mirror of
https://github.com/Snowflake-Labs/dlsync.git
synced 2025-12-17 16:41:26 +00:00
updated log message and changelog
This commit is contained in:
@@ -1,6 +1,10 @@
|
||||
# DLSync Changelog
|
||||
|
||||
This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
||||
## [2.6.0] - 2025-11-24
|
||||
### Added
|
||||
- Added support Masking Policy object type
|
||||
- Fixed log message unsupported object types in create script
|
||||
## [2.5.0] - 2025-11-06
|
||||
### Added
|
||||
- Added support for Dynamic Table object type
|
||||
|
||||
@@ -29,7 +29,7 @@ public class SqlTokenizer {
|
||||
private static final String IDENTIFIER_REGEX = "((?:\\\"[^\"]+\\\"\\.)|(?:[{}$a-zA-Z0-9_]+\\.))?((?:\\\"[^\"]+\\\"\\.)|(?:[{}$a-zA-Z0-9_]+\\.))?(?i)";
|
||||
private static final String MIGRATION_REGEX = VERSION_REGEX + AUTHOR_REGEX + CONTENT_REGEX + ROLL_BACK_REGEX + VERIFY_REGEX;
|
||||
|
||||
private static final String DDL_REGEX = ";\\n+(CREATE\\s+OR\\s+REPLACE\\s+(TRANSIENT\\s|HYBRID\\s|SECURE\\s)?(?<type>DYNAMIC TABLE|FILE FORMAT|VIEW|FUNCTION|PROCEDURE|TABLE|STREAM|SEQUENCE|STAGE|TASK|STREAMLIT|PIPE|ALERT|\\w+)\\s+(?<name>[\\\"\\w.]+)([\\s\\S]+?)(?=(;\\nCREATE\\s+)|(;$)))";
|
||||
private static final String DDL_REGEX = ";\\n+(CREATE\\s+OR\\s+REPLACE\\s+(TRANSIENT\\s|HYBRID\\s|SECURE\\s)?(?<type>DYNAMIC TABLE|FILE FORMAT|MASKING POLICY|VIEW|FUNCTION|PROCEDURE|TABLE|STREAM|SEQUENCE|STAGE|TASK|STREAMLIT|PIPE|ALERT|\\w+)\\s+(?<name>[\\\"\\w.]+)([\\s\\S]+?)(?=(;\\nCREATE\\s+)|(;$)))";
|
||||
|
||||
private static final String STRING_LITERAL_REGEX = "(?<!as\\s{1,5})'([^'\\\\]*(?:\\\\.[^'\\\\]*)*(?:''[^'\\\\]*)*)'";
|
||||
|
||||
@@ -254,9 +254,12 @@ public class SqlTokenizer {
|
||||
log.error("Unable to parse object type from DDL: {}", content);
|
||||
throw new RuntimeException("Unable to parse object type from DDL.");
|
||||
}
|
||||
ScriptObjectType objectType = Arrays.stream(ScriptObjectType.values())
|
||||
.filter(ot -> ot.getSingular().equalsIgnoreCase(type))
|
||||
.collect(Collectors.toList()).get(0);
|
||||
Optional<ScriptObjectType> optionalObjectType = Arrays.stream(ScriptObjectType.values()).filter( ot -> ot.getSingular().equalsIgnoreCase(type)).findFirst();
|
||||
if(!optionalObjectType.isPresent()) {
|
||||
log.error("Unsupported object type: {} found in DDL!", type);
|
||||
throw new RuntimeException("Unknown object type found in DDL: " + type);
|
||||
}
|
||||
ScriptObjectType objectType = optionalObjectType.get();
|
||||
|
||||
String fullObjectName = matcher.group("name");
|
||||
String scriptObjectName = fullObjectName.split("\\.")[2];
|
||||
|
||||
@@ -202,6 +202,8 @@ class SqlTokenizerTest {
|
||||
"create or replace transient table db1.schema1.table2 (col1 varchar, col2 number);\n" +
|
||||
"create or replace hybrid table db1.schema1.table3 (col1 varchar, col2 number);\n" +
|
||||
"create or replace table db1.schema1.\"table4\" (col1 varchar, col2 number);\n" +
|
||||
"create or replace dynamic table db1.schema1.dynamic_table1 (col1 varchar, col2 number)\n as SELECT id, name, COUNT(*) as count FROM db1.schema1.source_table GROUP BY id, name;\n" +
|
||||
"create or replace masking policy db1.schema1.masking_policy1 as (val string) returns string -> case when current_role() in ('ANALYST_ROLE', 'PUBLIC') then val else '****' end;\n" +
|
||||
"create or replace function db1.schema1.function1(arg1 varchar)\n" +
|
||||
"RETURNS VARCHAR(16777216)\n" +
|
||||
"LANGUAGE JAVASCRIPT\n" +
|
||||
@@ -215,6 +217,8 @@ class SqlTokenizerTest {
|
||||
ScriptFactory.getMigrationScript("db1", "schema1", ScriptObjectType.TABLES, "table2","create or replace transient table db1.schema1.table2 (col1 varchar, col2 number);"),
|
||||
ScriptFactory.getMigrationScript("db1", "schema1", ScriptObjectType.TABLES, "table3","create or replace hybrid table db1.schema1.table3 (col1 varchar, col2 number);"),
|
||||
ScriptFactory.getMigrationScript("db1", "schema1", ScriptObjectType.TABLES, "\"table4\"","create or replace table db1.schema1.\"table4\" (col1 varchar, col2 number);"),
|
||||
ScriptFactory.getMigrationScript("db1", "schema1", ScriptObjectType.DYNAMIC_TABLES, "dynamic_table1","create or replace dynamic table db1.schema1.dynamic_table1 (col1 varchar, col2 number)\n as SELECT id, name, COUNT(*) as count FROM db1.schema1.source_table GROUP BY id, name;"),
|
||||
ScriptFactory.getStateScript("db1", "schema1", ScriptObjectType.MASKING_POLICIES, "masking_policy1","create or replace masking policy db1.schema1.masking_policy1 as (val string) returns string -> case when current_role() in ('ANALYST_ROLE', 'PUBLIC') then val else '****' end;"),
|
||||
ScriptFactory.getStateScript("db1", "schema1", ScriptObjectType.FUNCTIONS, "function1","create or replace function db1.schema1.function1(arg1 varchar)\n" +
|
||||
"RETURNS VARCHAR(16777216)\n" +
|
||||
"LANGUAGE JAVASCRIPT\n" +
|
||||
@@ -621,4 +625,16 @@ class SqlTokenizerTest {
|
||||
"Exception message should indicate unknown script type");
|
||||
}
|
||||
|
||||
@Test
|
||||
void parseDdlScriptUnsupportedObjectType() {
|
||||
String ddl = "create or replace schema schema1;\n\nCREATE OR REPLACE UNKNOWN db1.schema1.OBJECT1;";
|
||||
|
||||
RuntimeException exception = assertThrows(RuntimeException.class, () -> {
|
||||
SqlTokenizer.parseDdlScripts(ddl, "db1", "schema1");
|
||||
}, "Should throw RuntimeException for unsupported object type");
|
||||
|
||||
assertEquals("Unknown object type found in DDL: UNKNOWN", exception.getMessage(),
|
||||
"Exception message should indicate unsupported DDL statement");
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user