Skip to content

Commit ee3e4f4

Browse files
committed
Merge branch 'refs/heads/master' into json_table_support
2 parents 8d3b1d6 + f7c9433 commit ee3e4f4

File tree

23 files changed

+42907
-298
lines changed

23 files changed

+42907
-298
lines changed

.github/workflows/ci.yml

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -39,9 +39,8 @@ jobs:
3939
runs-on: ${{ matrix.os }}
4040
strategy:
4141
matrix:
42-
# currently Windows does not work w/ code page related issues
4342
# os: [ ubuntu-latest, windows-latest, macos-latest ]
44-
os: [ ubuntu-latest, macos-latest ]
43+
os: [ ubuntu-latest, macos-latest ]
4544
steps:
4645
- uses: actions/checkout@main
4746
with:
@@ -87,7 +86,7 @@ jobs:
8786
run: sudo apt-get install -y xsltproc sphinx-common
8887

8988
- name: Install Python dependencies
90-
run: pip install manticore_sphinx_theme myst_parser sphinx_substitution_extensions sphinx_issues sphinx_inline_tabs pygments
89+
run: pip install manticore_sphinx_theme sphinx_javadoc_xml myst_parser sphinx_substitution_extensions sphinx_issues sphinx_inline_tabs pygments
9190

9291
- name: Build Sphinx documentation with Gradle
9392
run: FLOATING_TOC=false ./gradlew -DFLOATING_TOC=false gitChangelogTask renderRR xslt xmldoc sphinx

.gitignore

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,10 +8,10 @@
88

99
# Exclude the Auto-generated Changelog
1010
/src/site/sphinx/changelog.rst
11-
/src/site/sphinx/javadoc_stable.rst
1211
/src/site/sphinx/syntax_stable.rst
13-
/src/site/sphinx/javadoc_snapshot.rst
1412
/src/site/sphinx/syntax_snapshot.rst
13+
/src/site/sphinx/javadoc_stable.xml
14+
/src/site/sphinx/javadoc_snapshot.xml
1515

1616
# Generated by javacc-maven-plugin
1717
/bin

README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -76,11 +76,11 @@ JSQLParser-5.4 Snapshot and later use JavaCC-8 Snapshots for generating the pars
7676
Unfortunately the released JSQLParser-5.2 shows a performance deterioration caused by commit [30cf5d7](https://github.com/JSQLParser/JSqlParser/commit/30cf5d7b930ae0a076f49deb5cc841d39e62b3dc) related to `FunctionAllColumns()`.
7777
This has been resolved in JSQLParser 5.3-SNAPSHOT and JMH benchmarks have been added to avoid such regressions in the future. Further all `LOOKAHEAD` have been revised one by one, and we have gained back a very good performance of the Parser.
7878

79-
As per March-2026, the productions `Condition()`, `RegularCondition()` and `AndExpression()` have been refactored successfully. This resulted in a massive performance boost and seem to have solved most of the performance issues.
79+
As per March-2026, the productions `Condition()`, `RegularCondition()` and `AndExpression()` have been refactored successfully. Furthermore, we have overhauled Token definition and handling of Reserved Keywords. This resulted in a massive performance boost and seem to have solved most of the performance issues.
8080

8181
```text
8282
Benchmark (version) Mode Cnt Score Error Units
83-
JSQLParserBenchmark.parseSQLStatements latest avgt 15 15.908 ± 0.446 ms/op <-- March/26
83+
JSQLParserBenchmark.parseSQLStatements latest avgt 15 7.602 ± 0.135 ms/op <-- March/26
8484
JSQLParserBenchmark.parseSQLStatements 5.3 avgt 15 84.687 ± 3.321 ms/op
8585
JSQLParserBenchmark.parseSQLStatements 5.1 avgt 15 86.592 ± 5.781 ms/op
8686
```

build.gradle

Lines changed: 1 addition & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -249,12 +249,6 @@ tasks.register('xmldoc', Javadoc) {
249249
: "xmlDoclet/javadoc_stable.xml"
250250
)
251251

252-
def rstFile = reporting.file(
253-
version.endsWith("-SNAPSHOT")
254-
? "xmlDoclet/javadoc_snapshot.rst"
255-
: "xmlDoclet/javadoc_stable.rst"
256-
)
257-
258252
source = sourceSets.main.allJava
259253
// add any generated Java sources
260254
source += fileTree(layout.buildDirectory.dir("generated/javacc").get().asFile) {
@@ -271,16 +265,12 @@ tasks.register('xmldoc', Javadoc) {
271265
options.doclet = "com.manticore.tools.xmldoclet.XmlDoclet"
272266
title = "API $version"
273267

274-
options.addBooleanOption("rst", true)
275-
if (Boolean.parseBoolean(System.getProperty("FLOATING_TOC", "true"))) {
276-
options.addBooleanOption("withFloatingToc", true)
277-
}
278268
options.addStringOption("basePackage", "net.sf.jsqlparser")
279269
options.addStringOption("filename", outFile.getName())
280270

281271
doLast {
282272
copy {
283-
from rstFile
273+
from outFile
284274
into layout.projectDirectory.dir("src/site/sphinx/").asFile
285275
}
286276
}

pom.xml

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,7 @@
9999
<dependency>
100100
<groupId>org.assertj</groupId>
101101
<artifactId>assertj-core</artifactId>
102-
<version>3.27.3</version>
102+
<version>(3.27.7,)</version>
103103
<scope>test</scope>
104104
</dependency>
105105
<dependency>
@@ -277,7 +277,7 @@
277277
<plugin>
278278
<groupId>org.javacc.plugin</groupId>
279279
<artifactId>javacc-maven-plugin</artifactId>
280-
<version>3.0.3</version>
280+
<version>3.8.0</version>
281281
<executions>
282282
<execution>
283283
<id>javacc</id>
@@ -286,14 +286,14 @@
286286
<goal>jjtree-javacc</goal>
287287
</goals>
288288
<configuration>
289-
<grammarEncoding>UTF-8</grammarEncoding>
290-
<isStatic>false</isStatic>
291-
<debugParser>false</debugParser>
292-
<debugLookAhead>false</debugLookAhead>
293-
<codeGenerator>java</codeGenerator>
294-
295-
<!-- <unicodeInput>true</unicodeInput> -->
296-
<!-- <javaUnicodeEscape>true</javaUnicodeEscape> -->
289+
<javaccCmdLineArgs>
290+
<gen>-CODE_GENERATOR="Java"</gen>
291+
<enc>-GRAMMAR_ENCODING="UTF-8"</enc>
292+
</javaccCmdLineArgs>
293+
<jjtreeCmdLineArgs>
294+
<enc>-GRAMMAR_ENCODING="UTF-8"</enc>
295+
<gen>-CODE_GENERATOR="Java"</gen>
296+
</jjtreeCmdLineArgs>
297297
</configuration>
298298
</execution>
299299
</executions>
Lines changed: 205 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,205 @@
1+
/*-
2+
* #%L
3+
* JSQLParser library
4+
* %%
5+
* Copyright (C) 2004 - 2026 JSQLParser
6+
* %%
7+
* Dual licensed under GNU LGPL 2.1 or Apache License 2.0
8+
* #L%
9+
*/
10+
package net.sf.jsqlparser.statement.select;
11+
12+
import java.io.Serializable;
13+
import net.sf.jsqlparser.expression.StringValue;
14+
import net.sf.jsqlparser.parser.ASTNodeAccessImpl;
15+
16+
public class MySqlSelectIntoClause extends ASTNodeAccessImpl implements Serializable {
17+
18+
public enum Position {
19+
BEFORE_FROM, TRAILING
20+
}
21+
22+
public enum Type {
23+
OUTFILE, DUMPFILE
24+
}
25+
26+
public enum FieldsKeyword {
27+
FIELDS, COLUMNS
28+
}
29+
30+
private Position position = Position.TRAILING;
31+
private Type type;
32+
private StringValue fileName;
33+
private String characterSet;
34+
private FieldsKeyword fieldsKeyword;
35+
private StringValue fieldsTerminatedBy;
36+
private boolean fieldsOptionallyEnclosed;
37+
private StringValue fieldsEnclosedBy;
38+
private StringValue fieldsEscapedBy;
39+
private StringValue linesStartingBy;
40+
private StringValue linesTerminatedBy;
41+
42+
public Position getPosition() {
43+
return position;
44+
}
45+
46+
public void setPosition(Position position) {
47+
this.position = position;
48+
}
49+
50+
public MySqlSelectIntoClause withPosition(Position position) {
51+
this.setPosition(position);
52+
return this;
53+
}
54+
55+
public Type getType() {
56+
return type;
57+
}
58+
59+
public void setType(Type type) {
60+
this.type = type;
61+
}
62+
63+
public StringValue getFileName() {
64+
return fileName;
65+
}
66+
67+
public void setFileName(StringValue fileName) {
68+
this.fileName = fileName;
69+
}
70+
71+
public String getCharacterSet() {
72+
return characterSet;
73+
}
74+
75+
public void setCharacterSet(String characterSet) {
76+
this.characterSet = characterSet;
77+
}
78+
79+
public FieldsKeyword getFieldsKeyword() {
80+
return fieldsKeyword;
81+
}
82+
83+
public void setFieldsKeyword(FieldsKeyword fieldsKeyword) {
84+
this.fieldsKeyword = fieldsKeyword;
85+
}
86+
87+
public StringValue getFieldsTerminatedBy() {
88+
return fieldsTerminatedBy;
89+
}
90+
91+
public void setFieldsTerminatedBy(StringValue fieldsTerminatedBy) {
92+
this.fieldsTerminatedBy = fieldsTerminatedBy;
93+
}
94+
95+
public boolean isFieldsOptionallyEnclosed() {
96+
return fieldsOptionallyEnclosed;
97+
}
98+
99+
public void setFieldsOptionallyEnclosed(boolean fieldsOptionallyEnclosed) {
100+
this.fieldsOptionallyEnclosed = fieldsOptionallyEnclosed;
101+
}
102+
103+
public StringValue getFieldsEnclosedBy() {
104+
return fieldsEnclosedBy;
105+
}
106+
107+
public void setFieldsEnclosedBy(StringValue fieldsEnclosedBy) {
108+
this.fieldsEnclosedBy = fieldsEnclosedBy;
109+
}
110+
111+
public StringValue getFieldsEscapedBy() {
112+
return fieldsEscapedBy;
113+
}
114+
115+
public void setFieldsEscapedBy(StringValue fieldsEscapedBy) {
116+
this.fieldsEscapedBy = fieldsEscapedBy;
117+
}
118+
119+
public StringValue getLinesStartingBy() {
120+
return linesStartingBy;
121+
}
122+
123+
public void setLinesStartingBy(StringValue linesStartingBy) {
124+
this.linesStartingBy = linesStartingBy;
125+
}
126+
127+
public StringValue getLinesTerminatedBy() {
128+
return linesTerminatedBy;
129+
}
130+
131+
public void setLinesTerminatedBy(StringValue linesTerminatedBy) {
132+
this.linesTerminatedBy = linesTerminatedBy;
133+
}
134+
135+
public boolean hasFieldsClause() {
136+
return fieldsKeyword != null || fieldsTerminatedBy != null || fieldsEnclosedBy != null
137+
|| fieldsEscapedBy != null;
138+
}
139+
140+
public boolean hasLinesClause() {
141+
return linesStartingBy != null || linesTerminatedBy != null;
142+
}
143+
144+
public StringBuilder appendTo(StringBuilder builder) {
145+
builder.append("INTO ").append(type);
146+
appendFileName(builder);
147+
appendCharacterSet(builder);
148+
appendFieldsClause(builder);
149+
appendLinesClause(builder);
150+
return builder;
151+
}
152+
153+
private void appendFileName(StringBuilder builder) {
154+
if (fileName != null) {
155+
builder.append(" ").append(fileName);
156+
}
157+
}
158+
159+
private void appendCharacterSet(StringBuilder builder) {
160+
if (characterSet != null) {
161+
builder.append(" CHARACTER SET ").append(characterSet);
162+
}
163+
}
164+
165+
private void appendFieldsClause(StringBuilder builder) {
166+
if (!hasFieldsClause()) {
167+
return;
168+
}
169+
170+
builder.append(" ").append(fieldsKeyword != null ? fieldsKeyword : FieldsKeyword.FIELDS);
171+
172+
if (fieldsTerminatedBy != null) {
173+
builder.append(" TERMINATED BY ").append(fieldsTerminatedBy);
174+
}
175+
if (fieldsEnclosedBy != null) {
176+
builder.append(" ");
177+
if (fieldsOptionallyEnclosed) {
178+
builder.append("OPTIONALLY ");
179+
}
180+
builder.append("ENCLOSED BY ").append(fieldsEnclosedBy);
181+
}
182+
if (fieldsEscapedBy != null) {
183+
builder.append(" ESCAPED BY ").append(fieldsEscapedBy);
184+
}
185+
}
186+
187+
private void appendLinesClause(StringBuilder builder) {
188+
if (!hasLinesClause()) {
189+
return;
190+
}
191+
192+
builder.append(" LINES");
193+
if (linesStartingBy != null) {
194+
builder.append(" STARTING BY ").append(linesStartingBy);
195+
}
196+
if (linesTerminatedBy != null) {
197+
builder.append(" TERMINATED BY ").append(linesTerminatedBy);
198+
}
199+
}
200+
201+
@Override
202+
public String toString() {
203+
return appendTo(new StringBuilder()).toString();
204+
}
205+
}

src/main/java/net/sf/jsqlparser/statement/select/PlainSelect.java

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ public class PlainSelect extends Select {
3434
private BigQuerySelectQualifier bigQuerySelectQualifier = null;
3535
private List<SelectItem<?>> selectItems;
3636
private List<Table> intoTables;
37+
private MySqlSelectIntoClause mySqlSelectIntoClause;
3738
private FromItem fromItem;
3839
private List<LateralView> lateralViews;
3940
private List<Join> joins;
@@ -142,6 +143,14 @@ public void setIntoTables(List<Table> intoTables) {
142143
this.intoTables = intoTables;
143144
}
144145

146+
public MySqlSelectIntoClause getMySqlSelectIntoClause() {
147+
return mySqlSelectIntoClause;
148+
}
149+
150+
public void setMySqlSelectIntoClause(MySqlSelectIntoClause mySqlSelectIntoClause) {
151+
this.mySqlSelectIntoClause = mySqlSelectIntoClause;
152+
}
153+
145154
public List<SelectItem<?>> getSelectItems() {
146155
return selectItems;
147156
}
@@ -564,6 +573,12 @@ public StringBuilder appendSelectBodyTo(StringBuilder builder) {
564573
}
565574
}
566575

576+
if (mySqlSelectIntoClause != null
577+
&& mySqlSelectIntoClause
578+
.getPosition() == MySqlSelectIntoClause.Position.BEFORE_FROM) {
579+
builder.append(" ").append(mySqlSelectIntoClause);
580+
}
581+
567582
if (fromItem != null) {
568583
builder.append(" FROM ");
569584
if (isUsingOnly) {
@@ -646,6 +661,11 @@ public String toString() {
646661
StringBuilder builder = new StringBuilder();
647662
super.appendTo(builder);
648663

664+
if (mySqlSelectIntoClause != null
665+
&& mySqlSelectIntoClause.getPosition() == MySqlSelectIntoClause.Position.TRAILING) {
666+
builder.append(" ").append(mySqlSelectIntoClause);
667+
}
668+
649669
if (settings != null && !settings.isEmpty()) {
650670
builder.append(" SETTINGS ");
651671
UpdateSet.appendUpdateSetsTo(builder, settings);
@@ -698,6 +718,11 @@ public PlainSelect withIntoTables(List<Table> intoTables) {
698718
return this;
699719
}
700720

721+
public PlainSelect withMySqlSelectIntoClause(MySqlSelectIntoClause mySqlSelectIntoClause) {
722+
this.setMySqlSelectIntoClause(mySqlSelectIntoClause);
723+
return this;
724+
}
725+
701726
public PlainSelect withWhere(Expression where) {
702727
this.setWhere(where);
703728
return this;

0 commit comments

Comments
 (0)