Skip to content

Commit a879127

Browse files
feature: allow parsing BigQuery single pair quotes, e. g. "catalog.schema.tablename"
- fixes starlake-ai/jsqltranspiler#31 Signed-off-by: Andreas Reichel <[email protected]> Signed-off-by: manticore-projects <[email protected]>
1 parent 93ca661 commit a879127

File tree

8 files changed

+72
-25
lines changed

8 files changed

+72
-25
lines changed

.github/workflows/maven_deploy.yml

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,9 +14,11 @@ jobs:
1414
name: Java ${{ matrix.java }} building ...
1515

1616
steps:
17-
- uses: actions/checkout@v3
17+
- uses: actions/checkout@v4
18+
with:
19+
fetch-depth: 0
1820
- name: Set up Java ${{ matrix.java }}
19-
uses: actions/setup-java@v3
21+
uses: actions/setup-java@v4
2022
with:
2123
java-version: ${{ matrix.java }}
2224
distribution: 'temurin'

.github/workflows/sphinx.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ jobs:
1414
- name: Install dependencies
1515
run: pip install furo myst_parser sphinx-prompt sphinx_substitution_extensions sphinx_issues sphinx_inline_tabs pygments
1616
- name: Checkout project sources
17-
uses: actions/checkout@v2
17+
uses: actions/checkout@v4
1818
with:
1919
ref: master
2020
fetch-depth: 0

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
# Generated by maven
22
/target
33
/build
4+
/out
45

56
# Sphinx Theme related stuff, which shall be downloaded separately
67
/src/site/sphinx/_themes

build.gradle

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -187,10 +187,6 @@ test {
187187
environment = [ 'EXPORT_TEST_TO_FILE': 'True' ]
188188
useJUnitPlatform()
189189

190-
jacoco {
191-
excludes = ['net/sf/jsqlparser/parser/CCJSqlParserTokenManager']
192-
}
193-
194190
// set heap size for the test JVM(s)
195191
minHeapSize = "128m"
196192
maxHeapSize = "1G"

gradle.properties

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,13 @@
22
# The setting is particularly useful for tweaking memory settings.
33
org.gradle.jvmargs=-Xmx1G -Dfile.encoding=UTF-8 -XX:+HeapDumpOnOutOfMemoryError
44

5-
org.gradle.caching=true
5+
org.gradle.caching=false
66

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

1010
# Enable configure on demand.
11-
org.gradle.configureondemand=true
11+
org.gradle.configureondemand=false
1212

1313
# see https://docs.gradle.org/current/userguide/upgrading_version_8.html#xml_parsing_now_requires_recent_parsers
1414
systemProp.javax.xml.parsers.SAXParserFactory=com.sun.org.apache.xerces.internal.jaxp.SAXParserFactoryImpl

src/main/java/net/sf/jsqlparser/schema/MultiPartName.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,10 @@ static String unquote(String quotedIdentifier) {
2626
: null;
2727
}
2828

29+
static boolean isQuoted(String identifier) {
30+
return LEADING_TRAILING_QUOTES_PATTERN.matcher(identifier).find();
31+
}
32+
2933
String getFullyQualifiedName();
3034

3135
String getUnquotedName();

src/main/java/net/sf/jsqlparser/schema/Table.java

Lines changed: 32 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -63,36 +63,44 @@ public Table(String name) {
6363
}
6464

6565
public Table(String schemaName, String name) {
66-
setName(name);
6766
setSchemaName(schemaName);
67+
setName(name);
6868
}
6969

7070
public Table(Database database, String schemaName, String name) {
71-
setName(name);
72-
setSchemaName(schemaName);
7371
setDatabase(database);
72+
setSchemaName(schemaName);
73+
setName(name);
7474
}
7575

7676
public Table(String catalogName, String schemaName, String tableName) {
77-
setName(tableName);
7877
setSchemaName(schemaName);
7978
setDatabase(new Database(catalogName));
79+
setName(tableName);
8080
}
8181

8282
public Table(List<String> partItems) {
83-
this.partItems = new ArrayList<>(partItems);
84-
Collections.reverse(this.partItems);
83+
if (partItems.size() == 1) {
84+
setName(partItems.get(0));
85+
} else {
86+
this.partItems = new ArrayList<>(partItems);
87+
Collections.reverse(this.partItems);
88+
}
8589
}
8690

8791
public Table(List<String> partItems, List<String> partDelimiters) {
88-
if (partDelimiters.size() != partItems.size() - 1) {
89-
throw new IllegalArgumentException(
90-
"the length of the delimiters list must be 1 less than nameParts");
92+
if (partItems.size() == 1) {
93+
setName(partItems.get(0));
94+
} else {
95+
if (partDelimiters.size() != partItems.size() - 1) {
96+
throw new IllegalArgumentException(
97+
"the length of the delimiters list must be 1 less than nameParts");
98+
}
99+
this.partItems = new ArrayList<>(partItems);
100+
this.partDelimiters = new ArrayList<>(partDelimiters);
101+
Collections.reverse(this.partItems);
102+
Collections.reverse(this.partDelimiters);
91103
}
92-
this.partItems = new ArrayList<>(partItems);
93-
this.partDelimiters = new ArrayList<>(partDelimiters);
94-
Collections.reverse(this.partItems);
95-
Collections.reverse(this.partDelimiters);
96104
}
97105

98106
public String getCatalogName() {
@@ -159,7 +167,17 @@ public String getName() {
159167

160168

161169
public void setName(String name) {
162-
setIndex(NAME_IDX, name);
170+
// BigQuery seems to allow things like: `catalogName.schemaName.tableName` in only one pair
171+
// of quotes
172+
if (MultiPartName.isQuoted(name) && name.contains(".")) {
173+
partItems.clear();
174+
for (String unquotedIdentifier : MultiPartName.unquote(name).split("\\.")) {
175+
partItems.add("\"" + unquotedIdentifier + "\"");
176+
}
177+
Collections.reverse(partItems);
178+
} else {
179+
setIndex(NAME_IDX, name);
180+
}
163181
}
164182

165183
public String getDBLinkName() {

src/test/java/net/sf/jsqlparser/schema/TableTest.java

Lines changed: 28 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
import static org.assertj.core.api.Assertions.assertThat;
2323
import static org.assertj.core.api.Assertions.assertThatThrownBy;
2424
import static org.junit.jupiter.api.Assertions.assertEquals;
25+
import static org.junit.jupiter.api.Assertions.assertNull;
2526

2627
/**
2728
*
@@ -65,9 +66,7 @@ public <S> StringBuilder visit(Table tableName, S parameters) {
6566
return null;
6667
}
6768
};
68-
6969
deparser.visit((PlainSelect) select, null);
70-
7170
}
7271

7372
@Test
@@ -86,4 +85,31 @@ public void testConstructorDelimitersInappropriateSize() {
8685
.hasMessageContaining(
8786
"the length of the delimiters list must be 1 less than nameParts");
8887
}
88+
89+
@Test
90+
void testBigQueryFullQuotedName() throws JSQLParserException {
91+
String sqlStr = "select * from `d.s.t`";
92+
PlainSelect select = (PlainSelect) CCJSqlParserUtil.parse(sqlStr);
93+
Table table = (Table) select.getFromItem();
94+
95+
assertEquals("\"d\"", table.getCatalogName());
96+
assertEquals("\"s\"", table.getSchemaName());
97+
assertEquals("\"t\"", table.getName());
98+
99+
assertEquals("d", table.getUnquotedDatabaseName());
100+
assertEquals("s", table.getUnquotedSchemaName());
101+
assertEquals("t", table.getUnquotedName());
102+
103+
sqlStr = "select * from `s.t`";
104+
select = (PlainSelect) CCJSqlParserUtil.parse(sqlStr);
105+
table = (Table) select.getFromItem();
106+
107+
assertNull(table.getCatalogName());
108+
assertEquals("\"s\"", table.getSchemaName());
109+
assertEquals("\"t\"", table.getName());
110+
111+
assertNull(table.getUnquotedDatabaseName());
112+
assertEquals("s", table.getUnquotedSchemaName());
113+
assertEquals("t", table.getUnquotedName());
114+
}
89115
}

0 commit comments

Comments
 (0)