Skip to content

Commit bb13af8

Browse files
committed
Scan an array once to tell a list comprehension apart
`isListComprehensionAhead()` called `getToken(i)` for each token, which walks from the current token every time: parsing a 10,000-element array took seconds. It now follows the token chain.
1 parent 9459631 commit bb13af8

2 files changed

Lines changed: 15 additions & 4 deletions

File tree

‎src/main/jjtree/net/sf/jsqlparser/parser/JSqlParserCC.jjt‎

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1661,13 +1661,13 @@ public class CCJSqlParser extends AbstractJSqlParser<CCJSqlParser> {
16611661

16621662
/** Whether a {@code [} opens DuckDB's {@code [expr FOR x IN list]}: FOR at its top level. */
16631663
private boolean isListComprehensionAhead() {
1664-
if (!"[".equals(getToken(1).image)) {
1664+
Token token = getToken(1);
1665+
if (!"[".equals(token.image)) {
16651666
return false;
16661667
}
16671668
int depth = 0;
1668-
for (int i = 1;; i++) {
1669-
Token token = getToken(i);
1670-
if (token == null || token.kind == EOF || ";".equals(token.image)) {
1669+
for (;; token = nextWithItemToken(token)) {
1670+
if (token.kind == EOF || ";".equals(token.image)) {
16711671
return false;
16721672
}
16731673
if ("(".equals(token.image) || "[".equals(token.image) || "{".equals(token.image)) {

‎src/test/java/net/sf/jsqlparser/statement/select/DuckDBTest.java‎

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@
3434
import net.sf.jsqlparser.util.TablesNamesFinder;
3535
import org.junit.jupiter.api.Assertions;
3636
import org.junit.jupiter.api.Test;
37+
import org.junit.jupiter.api.Timeout;
3738

3839
import java.util.Arrays;
3940
import java.util.HashSet;
@@ -1010,4 +1011,14 @@ void testListComprehension() throws JSQLParserException {
10101011
new HashSet<>(new TablesNamesFinder<>().getTables(CCJSqlParserUtil.parse(
10111012
"SELECT [x FOR x IN (SELECT list(a) FROM u)] FROM t"))));
10121013
}
1014+
1015+
@Test
1016+
@Timeout(10)
1017+
void testLargeArrayIsScannedOnce() throws JSQLParserException {
1018+
StringBuilder sql = new StringBuilder("SELECT [0");
1019+
for (int i = 1; i < 20000; i++) {
1020+
sql.append(", ").append(i);
1021+
}
1022+
CCJSqlParserUtil.parse(sql.append("]").toString());
1023+
}
10131024
}

0 commit comments

Comments
 (0)