Skip to content

Commit 327524b

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 dcdb70e commit 327524b

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
@@ -1652,13 +1652,13 @@ public class CCJSqlParser extends AbstractJSqlParser<CCJSqlParser> {
16521652

16531653
/** Whether a {@code [} opens DuckDB's {@code [expr FOR x IN list]}: FOR at its top level. */
16541654
private boolean isListComprehensionAhead() {
1655-
if (!"[".equals(getToken(1).image)) {
1655+
Token token = getToken(1);
1656+
if (!"[".equals(token.image)) {
16561657
return false;
16571658
}
16581659
int depth = 0;
1659-
for (int i = 1;; i++) {
1660-
Token token = getToken(i);
1661-
if (token == null || token.kind == EOF || ";".equals(token.image)) {
1660+
for (;; token = nextWithItemToken(token)) {
1661+
if (token.kind == EOF || ";".equals(token.image)) {
16621662
return false;
16631663
}
16641664
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;
@@ -927,4 +928,14 @@ void testListComprehension() throws JSQLParserException {
927928
new HashSet<>(new TablesNamesFinder<>().getTables(CCJSqlParserUtil.parse(
928929
"SELECT [x FOR x IN (SELECT list(a) FROM u)] FROM t"))));
929930
}
931+
932+
@Test
933+
@Timeout(10)
934+
void testLargeArrayIsScannedOnce() throws JSQLParserException {
935+
StringBuilder sql = new StringBuilder("SELECT [0");
936+
for (int i = 1; i < 20000; i++) {
937+
sql.append(", ").append(i);
938+
}
939+
CCJSqlParserUtil.parse(sql.append("]").toString());
940+
}
930941
}

0 commit comments

Comments
 (0)