Skip to content

Commit

Permalink
feature: allow parsing BigQuery single pair quotes, e. g. "catalog.sc…
Browse files Browse the repository at this point in the history
…hema.tablename"

- fixes starlake-ai/jsqltranspiler#31

Signed-off-by: Andreas Reichel <[email protected]>
Signed-off-by: manticore-projects <[email protected]>
  • Loading branch information
manticore-projects committed Aug 20, 2024
1 parent 93ca661 commit a879127
Show file tree
Hide file tree
Showing 8 changed files with 72 additions and 25 deletions.
6 changes: 4 additions & 2 deletions .github/workflows/maven_deploy.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,11 @@ jobs:
name: Java ${{ matrix.java }} building ...

steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Set up Java ${{ matrix.java }}
uses: actions/setup-java@v3
uses: actions/setup-java@v4
with:
java-version: ${{ matrix.java }}
distribution: 'temurin'
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/sphinx.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ jobs:
- name: Install dependencies
run: pip install furo myst_parser sphinx-prompt sphinx_substitution_extensions sphinx_issues sphinx_inline_tabs pygments
- name: Checkout project sources
uses: actions/checkout@v2
uses: actions/checkout@v4
with:
ref: master
fetch-depth: 0
Expand Down
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
# Generated by maven
/target
/build
/out

# Sphinx Theme related stuff, which shall be downloaded separately
/src/site/sphinx/_themes
Expand Down
4 changes: 0 additions & 4 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -187,10 +187,6 @@ test {
environment = [ 'EXPORT_TEST_TO_FILE': 'True' ]
useJUnitPlatform()

jacoco {
excludes = ['net/sf/jsqlparser/parser/CCJSqlParserTokenManager']
}

// set heap size for the test JVM(s)
minHeapSize = "128m"
maxHeapSize = "1G"
Expand Down
4 changes: 2 additions & 2 deletions gradle.properties
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,13 @@
# The setting is particularly useful for tweaking memory settings.
org.gradle.jvmargs=-Xmx1G -Dfile.encoding=UTF-8 -XX:+HeapDumpOnOutOfMemoryError

org.gradle.caching=true
org.gradle.caching=false

# Modularise your project and enable parallel build
org.gradle.parallel=true

# Enable configure on demand.
org.gradle.configureondemand=true
org.gradle.configureondemand=false

# see https://docs.gradle.org/current/userguide/upgrading_version_8.html#xml_parsing_now_requires_recent_parsers
systemProp.javax.xml.parsers.SAXParserFactory=com.sun.org.apache.xerces.internal.jaxp.SAXParserFactoryImpl
Expand Down
4 changes: 4 additions & 0 deletions src/main/java/net/sf/jsqlparser/schema/MultiPartName.java
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,10 @@ static String unquote(String quotedIdentifier) {
: null;
}

static boolean isQuoted(String identifier) {
return LEADING_TRAILING_QUOTES_PATTERN.matcher(identifier).find();
}

String getFullyQualifiedName();

String getUnquotedName();
Expand Down
46 changes: 32 additions & 14 deletions src/main/java/net/sf/jsqlparser/schema/Table.java
Original file line number Diff line number Diff line change
Expand Up @@ -63,36 +63,44 @@ public Table(String name) {
}

public Table(String schemaName, String name) {
setName(name);
setSchemaName(schemaName);
setName(name);
}

public Table(Database database, String schemaName, String name) {
setName(name);
setSchemaName(schemaName);
setDatabase(database);
setSchemaName(schemaName);
setName(name);
}

public Table(String catalogName, String schemaName, String tableName) {
setName(tableName);
setSchemaName(schemaName);
setDatabase(new Database(catalogName));
setName(tableName);
}

public Table(List<String> partItems) {
this.partItems = new ArrayList<>(partItems);
Collections.reverse(this.partItems);
if (partItems.size() == 1) {
setName(partItems.get(0));
} else {
this.partItems = new ArrayList<>(partItems);
Collections.reverse(this.partItems);
}
}

public Table(List<String> partItems, List<String> partDelimiters) {
if (partDelimiters.size() != partItems.size() - 1) {
throw new IllegalArgumentException(
"the length of the delimiters list must be 1 less than nameParts");
if (partItems.size() == 1) {
setName(partItems.get(0));
} else {
if (partDelimiters.size() != partItems.size() - 1) {
throw new IllegalArgumentException(
"the length of the delimiters list must be 1 less than nameParts");
}
this.partItems = new ArrayList<>(partItems);
this.partDelimiters = new ArrayList<>(partDelimiters);
Collections.reverse(this.partItems);
Collections.reverse(this.partDelimiters);
}
this.partItems = new ArrayList<>(partItems);
this.partDelimiters = new ArrayList<>(partDelimiters);
Collections.reverse(this.partItems);
Collections.reverse(this.partDelimiters);
}

public String getCatalogName() {
Expand Down Expand Up @@ -159,7 +167,17 @@ public String getName() {


public void setName(String name) {
setIndex(NAME_IDX, name);
// BigQuery seems to allow things like: `catalogName.schemaName.tableName` in only one pair
// of quotes
if (MultiPartName.isQuoted(name) && name.contains(".")) {
partItems.clear();
for (String unquotedIdentifier : MultiPartName.unquote(name).split("\\.")) {
partItems.add("\"" + unquotedIdentifier + "\"");
}
Collections.reverse(partItems);
} else {
setIndex(NAME_IDX, name);
}
}

public String getDBLinkName() {
Expand Down
30 changes: 28 additions & 2 deletions src/test/java/net/sf/jsqlparser/schema/TableTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatThrownBy;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNull;

/**
*
Expand Down Expand Up @@ -65,9 +66,7 @@ public <S> StringBuilder visit(Table tableName, S parameters) {
return null;
}
};

deparser.visit((PlainSelect) select, null);

}

@Test
Expand All @@ -86,4 +85,31 @@ public void testConstructorDelimitersInappropriateSize() {
.hasMessageContaining(
"the length of the delimiters list must be 1 less than nameParts");
}

@Test
void testBigQueryFullQuotedName() throws JSQLParserException {
String sqlStr = "select * from `d.s.t`";
PlainSelect select = (PlainSelect) CCJSqlParserUtil.parse(sqlStr);
Table table = (Table) select.getFromItem();

assertEquals("\"d\"", table.getCatalogName());
assertEquals("\"s\"", table.getSchemaName());
assertEquals("\"t\"", table.getName());

assertEquals("d", table.getUnquotedDatabaseName());
assertEquals("s", table.getUnquotedSchemaName());
assertEquals("t", table.getUnquotedName());

sqlStr = "select * from `s.t`";
select = (PlainSelect) CCJSqlParserUtil.parse(sqlStr);
table = (Table) select.getFromItem();

assertNull(table.getCatalogName());
assertEquals("\"s\"", table.getSchemaName());
assertEquals("\"t\"", table.getName());

assertNull(table.getUnquotedDatabaseName());
assertEquals("s", table.getUnquotedSchemaName());
assertEquals("t", table.getUnquotedName());
}
}

0 comments on commit a879127

Please sign in to comment.