Skip to content

Commit

Permalink
added option in parserDdl to parse or skip the annotations that are c…
Browse files Browse the repository at this point in the history
…omments in the DDL file
  • Loading branch information
gurminder71 committed Sep 27, 2024
1 parent 36cc8f9 commit 336b9f2
Show file tree
Hide file tree
Showing 3 changed files with 53 additions and 19 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@
import java.util.Set;
import java.util.TreeMap;
import java.util.function.Function;
import java.util.regex.Pattern;
import java.util.stream.Collectors;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
Expand Down Expand Up @@ -707,10 +708,26 @@ private static String getDatabaseNameFromAlterDatabase(List<ASTddl_statement> st
* @throws DdlDiffException if there is an error in parsing the DDL
*/
public static List<ASTddl_statement> parseDdl(String original) throws DdlDiffException {
return parseDdl(original, false);
}

/**
* Parses the Cloud Spanner Schema (DDL) string to a list of AST DDL statements.
*
* @param original DDL to parse
* @param parseAnnotationInComments If true then the annotations that appear as comments
* "-- @ANNOTATION <annotation>" will be parsed
* @return List of parsed DDL statements
*/
public static List<ASTddl_statement> parseDdl(String original, boolean parseAnnotationInComments)
throws DdlDiffException {
// the annotations are prefixed with "--" so that SQL file remains valid.
// strip the comment prefix before so that annotations can be parsed.
// otherwise they will be ignored as comment lines
original = original.replaceAll("-- *@", "@");
if (parseAnnotationInComments) {
original =
Pattern.compile("^\\s*--\\s+@", Pattern.MULTILINE).matcher(original).replaceAll("@");
}

// Remove "--" comments and split by ";"
List<String> statements = Splitter.on(';').splitToList(original.replaceAll("--.*(\n|$)", ""));
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
package com.google.cloud.solutions.spannerddl.parser;

import static com.google.common.truth.Truth.assertThat;
import static com.google.common.truth.Truth.assertWithMessage;
import static org.junit.Assert.fail;

import com.google.cloud.solutions.spannerddl.diff.DdlDiff;
import com.google.cloud.solutions.spannerddl.diff.DdlDiffException;
import com.google.cloud.solutions.spannerddl.testUtils.ReadTestDatafile;
import java.io.IOException;
import java.io.StringReader;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
Expand All @@ -32,28 +34,43 @@ public void validateAnnotations() throws IOException {
String segmentName = test.getKey();

try {
DdlParser parser = new DdlParser(new StringReader(test.getValue()));
parser.ddl_statement();
Node tableStatement = parser.jjtree.rootNode().jjtGetChild(0);
// first get all the annotations without removing the comment prefix
List<String> annotations = getTableAnnotations(test.getValue(), false);

// get all annotations
List<String> annotations = new ArrayList<>();
for (int i = 0, count = tableStatement.jjtGetNumChildren(); i < count; i++) {
Node child = tableStatement.jjtGetChild(i);
if (child instanceof ASTannotation) {
annotations.add(((ASTannotation) child).getAnnotation());
}
}
// annotations should be empty
assertThat(annotations).isEmpty();

// now get all the annotations after removing the comment prefix
annotations = getTableAnnotations(test.getValue(), true);

List<String> expectedList =
expected != null ? Arrays.asList(expected.split("\n")) : Collections.emptyList();

assertWithMessage("Mismatch for section " + segmentName)
.that(annotations)
.isEqualTo(expectedList);
} catch (ParseException e) {
} catch (DdlDiffException e) {
fail("Failed to parse section: '" + segmentName + "': " + e);
}
}
}

private List<String> getTableAnnotations(String ddl, boolean parseAnnotations)
throws DdlDiffException {
List<String> annotations = new ArrayList<>();

List<ASTddl_statement> statements = DdlDiff.parseDdl(ddl, parseAnnotations);
for (ASTddl_statement statement : statements) {
if (statement.jjtGetChild(0).getId() == DdlParserTreeConstants.JJTCREATE_TABLE_STATEMENT) {
Node tableStatement = statement.jjtGetChild(0);
for (int i = 0, count = tableStatement.jjtGetNumChildren(); i < count; i++) {
Node child = tableStatement.jjtGetChild(i);
if (child instanceof ASTannotation) {
annotations.add(((ASTannotation) child).getAnnotation());
}
}
}
}
return annotations;
}
}
10 changes: 5 additions & 5 deletions src/test/resources/annotations.txt
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
== Test 1 all column annotations

CREATE TABLE test1 (
@ANNOTATION DEPRECATED,
@ANNOTATION PII,
@ANNOTATION TAG.business(internal),
@ANNOTATION TAG.business(key1,key2),
@ANNOTATION TAG.business(key1=val1,key2=value),
-- @ANNOTATION DEPRECATED,
-- @ANNOTATION PII,
-- @ANNOTATION TAG.business(internal),
-- @ANNOTATION TAG.business(key1,key2),
-- @ANNOTATION TAG.business(key1=val1,key2=value),
id STRING(36),
) PRIMARY KEY (id)

Expand Down

0 comments on commit 336b9f2

Please sign in to comment.