Skip to content

Commit 3ea7384

Browse files
committed
feat: Support for CREATE VIEW statements
1 parent 96fab0c commit 3ea7384

File tree

8 files changed

+139
-29
lines changed

8 files changed

+139
-29
lines changed

src/main/java/com/google/cloud/solutions/spannerddl/diff/DatabaseDefinition.java

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
import com.google.cloud.solutions.spannerddl.parser.ASTcreate_schema_statement;
2828
import com.google.cloud.solutions.spannerddl.parser.ASTcreate_search_index_statement;
2929
import com.google.cloud.solutions.spannerddl.parser.ASTcreate_table_statement;
30+
import com.google.cloud.solutions.spannerddl.parser.ASTcreate_view_statement;
3031
import com.google.cloud.solutions.spannerddl.parser.ASTddl_statement;
3132
import com.google.cloud.solutions.spannerddl.parser.ASTforeign_key;
3233
import com.google.cloud.solutions.spannerddl.parser.ASTrow_deletion_policy_clause;
@@ -64,6 +65,7 @@ public static DatabaseDefinition create(List<ASTddl_statement> statements) {
6465
LinkedHashMap<String, ASTcreate_change_stream_statement> changeStreams = new LinkedHashMap<>();
6566
LinkedHashMap<String, String> alterDatabaseOptions = new LinkedHashMap<>();
6667
LinkedHashMap<String, ASTcreate_schema_statement> schemas = new LinkedHashMap<>();
68+
LinkedHashMap<String, ASTcreate_view_statement> views = new LinkedHashMap<>();
6769

6870
for (ASTddl_statement ddlStatement : statements) {
6971
final SimpleNode statement = (SimpleNode) ddlStatement.jjtGetChild(0);
@@ -139,6 +141,14 @@ public static DatabaseDefinition create(List<ASTddl_statement> statements) {
139141
(ASTcreate_schema_statement)
140142
((ASTcreate_or_replace_statement) statement).getSchemaObject());
141143
break;
144+
case DdlParserTreeConstants.JJTCREATE_VIEW_STATEMENT:
145+
views.put(
146+
((ASTcreate_view_statement)
147+
((ASTcreate_or_replace_statement) statement).getSchemaObject())
148+
.getName(),
149+
(ASTcreate_view_statement)
150+
((ASTcreate_or_replace_statement) statement).getSchemaObject());
151+
break;
142152
default:
143153
throw new IllegalArgumentException(
144154
"Unsupported statement: " + AstTreeUtils.tokensToString(ddlStatement));
@@ -157,7 +167,8 @@ public static DatabaseDefinition create(List<ASTddl_statement> statements) {
157167
ImmutableMap.copyOf(ttls),
158168
ImmutableMap.copyOf(changeStreams),
159169
ImmutableMap.copyOf(alterDatabaseOptions),
160-
ImmutableMap.copyOf(schemas));
170+
ImmutableMap.copyOf(schemas),
171+
ImmutableMap.copyOf(views));
161172
}
162173

163174
public abstract ImmutableMap<String, ASTcreate_table_statement> tablesInCreationOrder();
@@ -175,4 +186,6 @@ public static DatabaseDefinition create(List<ASTddl_statement> statements) {
175186
abstract ImmutableMap<String, String> alterDatabaseOptions();
176187

177188
abstract ImmutableMap<String, ASTcreate_schema_statement> schemas();
189+
190+
abstract ImmutableMap<String, ASTcreate_view_statement> views();
178191
}

src/main/java/com/google/cloud/solutions/spannerddl/diff/DdlDiff.java

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@
3131
import com.google.cloud.solutions.spannerddl.parser.ASTcreate_schema_statement;
3232
import com.google.cloud.solutions.spannerddl.parser.ASTcreate_search_index_statement;
3333
import com.google.cloud.solutions.spannerddl.parser.ASTcreate_table_statement;
34+
import com.google.cloud.solutions.spannerddl.parser.ASTcreate_view_statement;
3435
import com.google.cloud.solutions.spannerddl.parser.ASTddl_statement;
3536
import com.google.cloud.solutions.spannerddl.parser.ASTforeign_key;
3637
import com.google.cloud.solutions.spannerddl.parser.ASToptions_clause;
@@ -103,6 +104,7 @@ public class DdlDiff {
103104
private final MapDifference<String, ASTcreate_search_index_statement> searchIndexDifferences;
104105
private final String databaseName; // for alter Database
105106
private final MapDifference<String, ASTcreate_schema_statement> schemaDifferences;
107+
private final MapDifference<String, ASTcreate_view_statement> viewDifferences;
106108

107109
private DdlDiff(DatabaseDefinition originalDb, DatabaseDefinition newDb, String databaseName)
108110
throws DdlDiffException {
@@ -122,6 +124,7 @@ private DdlDiff(DatabaseDefinition originalDb, DatabaseDefinition newDb, String
122124
this.searchIndexDifferences =
123125
Maps.difference(originalDb.searchIndexes(), newDb.searchIndexes());
124126
this.schemaDifferences = Maps.difference(originalDb.schemas(), newDb.schemas());
127+
this.viewDifferences = Maps.difference(originalDb.views(), newDb.views());
125128

126129
if (!alterDatabaseOptionsDifferences.areEqual() && Strings.isNullOrEmpty(databaseName)) {
127130
// should never happen, but...
@@ -197,6 +200,14 @@ public List<String> generateDifferenceStatements(Map<String, Boolean> options)
197200
}
198201
}
199202

203+
// Drop deleted views.
204+
if (options.get(ALLOW_DROP_STATEMENTS_OPT)) {
205+
for (String viewName : viewDifferences.entriesOnlyOnLeft().keySet()) {
206+
LOG.info("Dropping deleted view: {}", viewName);
207+
output.add("DROP VIEW " + viewName);
208+
}
209+
}
210+
200211
// drop deleted search indexes.
201212
if (options.get(ALLOW_DROP_STATEMENTS_OPT)) {
202213
for (String searchIndexName : searchIndexDifferences.entriesOnlyOnLeft().keySet()) {
@@ -426,6 +437,19 @@ public List<String> generateDifferenceStatements(Map<String, Boolean> options)
426437

427438
// Add all new search indexes
428439

440+
// Create new views.
441+
for (ASTcreate_view_statement view : viewDifferences.entriesOnlyOnRight().values()) {
442+
LOG.info("Creating new view: {}", view.getName());
443+
output.add("CREATE OR REPLACE " + view.toStringBase());
444+
}
445+
446+
// Alter existing views.
447+
for (ValueDifference<ASTcreate_view_statement> difference :
448+
viewDifferences.entriesDiffering().values()) {
449+
LOG.info("Altering modified view: {}", difference.leftValue().getName());
450+
output.add("CREATE OR REPLACE " + difference.leftValue().toStringBase());
451+
}
452+
429453
return output.build();
430454
}
431455

@@ -813,6 +837,7 @@ public static List<ASTddl_statement> parseDdl(String original, boolean parseAnno
813837
break;
814838
case DdlParserTreeConstants.JJTCREATE_INDEX_STATEMENT:
815839
case DdlParserTreeConstants.JJTALTER_DATABASE_STATEMENT:
840+
case DdlParserTreeConstants.JJTCREATE_VIEW_STATEMENT:
816841
case DdlParserTreeConstants.JJTCREATE_CHANGE_STREAM_STATEMENT:
817842
case DdlParserTreeConstants.JJTCREATE_SEARCH_INDEX_STATEMENT:
818843
// no-op - allowed
@@ -823,6 +848,7 @@ public static List<ASTddl_statement> parseDdl(String original, boolean parseAnno
823848
.getSchemaObject()
824849
.getId()) {
825850
case DdlParserTreeConstants.JJTCREATE_SCHEMA_STATEMENT:
851+
case DdlParserTreeConstants.JJTCREATE_VIEW_STATEMENT:
826852
// no-op - allowed
827853
break;
828854
default:

src/main/java/com/google/cloud/solutions/spannerddl/parser/ASTcreate_view_statement.java

Lines changed: 48 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,15 +15,60 @@
1515
*/
1616
package com.google.cloud.solutions.spannerddl.parser;
1717

18-
// TODO
18+
import com.google.cloud.solutions.spannerddl.diff.AstTreeUtils;
19+
import com.google.common.base.Joiner;
20+
import com.google.common.collect.ImmutableSet;
21+
1922
public class ASTcreate_view_statement extends SimpleNode {
2023
public ASTcreate_view_statement(int id) {
2124
super(id);
22-
throw new UnsupportedOperationException("Not Implemented");
2325
}
2426

2527
public ASTcreate_view_statement(DdlParser p, int id) {
2628
super(p, id);
27-
throw new UnsupportedOperationException("Not Implemented");
29+
}
30+
31+
public String toStringBase() {
32+
validateChildren();
33+
return Joiner.on(" ")
34+
.skipNulls()
35+
.join(
36+
"VIEW",
37+
getName(),
38+
"SQL SECURITY",
39+
AstTreeUtils.tokensToString(AstTreeUtils.getOptionalChildByType(children, ASTsql_security.class)),
40+
"AS",
41+
AstTreeUtils.tokensToString(AstTreeUtils.getOptionalChildByType(children, ASTview_definition.class))
42+
);
43+
}
44+
45+
private void validateChildren() {
46+
AstTreeUtils.validateChildrenClasses(
47+
children, ImmutableSet.of(ASTname.class, ASTsql_security.class, ASTview_definition.class));
48+
}
49+
50+
public String getName() {
51+
return AstTreeUtils.tokensToString(AstTreeUtils.getChildByType(children, ASTname.class), false);
52+
}
53+
54+
@Override
55+
public String toString() {
56+
return Joiner.on(" ")
57+
.skipNulls()
58+
.join(
59+
"CREATE",
60+
toStringBase()
61+
);
62+
}
63+
64+
65+
@Override
66+
public boolean equals(Object obj) {
67+
return (obj instanceof ASTcreate_view_statement) && toString().equals(obj.toString());
68+
}
69+
70+
@Override
71+
public int hashCode() {
72+
return toString().hashCode();
2873
}
2974
}

src/test/java/com/google/cloud/solutions/spannerddl/diff/DdlDiffFromFilesTest.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,7 @@ public void compareDddTextFiles() throws IOException {
8484
.filter(
8585
statement ->
8686
!statement.matches(
87-
".*DROP (SCHEMA|TABLE|COLUMN|CHANGE STREAM|SEARCH INDEX).*"))
87+
".*DROP (SCHEMA|TABLE|COLUMN|CHANGE STREAM|SEARCH INDEX|VIEW).*"))
8888
.collect(Collectors.toList());
8989

9090
// remove any drop indexes from the expectedResults if they do not have an equivalent

src/test/resources/ddlParserUnsupported.txt

Lines changed: 1 addition & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -24,14 +24,6 @@ ALTER TABLE Albums DROP ROW DELETION POLICY
2424
ALTER TABLE Albums
2525
REPLACE ROW DELETION POLICY (OLDER_THAN(timestamp_column, INTERVAL 1 DAY))
2626

27-
== Test 3
28-
29-
CREATE OR REPLACE VIEW test1 SQL SECURITY INVOKER AS SELECT * from test2
30-
31-
== Test 4
32-
33-
CREATE VIEW test1 SQL SECURITY INVOKER AS SELECT * from test2
34-
3527
== Test 6
3628

3729
drop change stream test1
@@ -68,18 +60,6 @@ GRANT SELECT ON TABLE table_list TO ROLE role_list
6860

6961
REVOKE SELECT ON TABLE table_list TO ROLE role_list
7062

71-
== Test 12a // TODO views
72-
73-
CREATE VIEW view_name AS query
74-
75-
== Test 12b drop view not supported
76-
77-
DROP VIEW view_name
78-
79-
== Test 13 // TODO views
80-
81-
CREATE OR REPLACE VIEW view_name AS query
82-
8363
== Test 14a // TODO sequences
8464

8565
CREATE SEQUENCE IF NOT EXISTS sequence_name OPTIONS ( sequence_kind='bit_reversed_positive' )
@@ -163,4 +143,4 @@ ALTER SEARCH INDEX AlbumsIndex ADD STORED COLUMN test
163143

164144
ALTER SEARCH INDEX AlbumsIndex ADD COLUMN add_token_column
165145

166-
==
146+
==

src/test/resources/expectedDdlDiff.txt

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -350,4 +350,18 @@ DROP SCHEMA schema2
350350
CREATE SCHEMA schema3
351351
CREATE TABLE schema3.table1 ( col1 INT64 ) PRIMARY KEY (col1 ASC)
352352

353-
==
353+
== TEST 68 Create view
354+
355+
CREATE OR REPLACE VIEW view1 SQL SECURITY INVOKER AS SELECT * FROM test1
356+
CREATE OR REPLACE VIEW view2 SQL SECURITY DEFINER AS SELECT * FROM test2
357+
358+
== TEST 69 Replace view
359+
360+
CREATE OR REPLACE VIEW view1 SQL SECURITY INVOKER AS SELECT * FROM test1
361+
CREATE OR REPLACE VIEW view2 SQL SECURITY DEFINER AS SELECT * FROM test2
362+
363+
== TEST 70 Dropping view
364+
365+
DROP VIEW view2
366+
367+
==

src/test/resources/newDdl.txt

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -563,4 +563,22 @@ CREATE TABLE schema3.table1 (
563563
col1 INT64,
564564
)PRIMARY KEY (col1);
565565

566-
==
566+
== TEST 68 Create view
567+
568+
CREATE VIEW view1 SQL SECURITY INVOKER AS SELECT * FROM test1;
569+
CREATE OR REPLACE VIEW view2 SQL SECURITY DEFINER AS SELECT * FROM test2;
570+
571+
== TEST 69 Replace view
572+
573+
CREATE VIEW view1 SQL SECURITY DEFINER
574+
AS SELECT *
575+
FROM test2;
576+
CREATE OR REPLACE VIEW view2 SQL SECURITY INVOKER
577+
AS SELECT *
578+
FROM test1;
579+
580+
== TEST 70 Dropping view
581+
582+
CREATE VIEW view1 SQL SECURITY INVOKER AS SELECT * from test1;
583+
584+
==

src/test/resources/originalDdl.txt

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -561,4 +561,18 @@ CREATE TABLE schema2.table1 (
561561
)PRIMARY KEY (col1);
562562

563563

564-
==
564+
== TEST 68 Create view
565+
566+
-- nothing
567+
568+
== TEST 69 Replace view
569+
570+
CREATE VIEW view1 SQL SECURITY INVOKER AS SELECT * FROM test1;
571+
CREATE OR REPLACE VIEW view2 SQL SECURITY DEFINER AS SELECT * FROM test2;
572+
573+
== TEST 70 Dropping view
574+
575+
CREATE VIEW view1 SQL SECURITY INVOKER AS SELECT * FROM test1;
576+
CREATE OR REPLACE VIEW view2 SQL SECURITY DEFINER AS SELECT * FROM test2;
577+
578+
==

0 commit comments

Comments
 (0)