Skip to content

Commit 4951c00

Browse files
Jamesclaude
authored andcommitted
Never vendor the parser: fetch it from Maven everywhere, including the .bat path
A fresh clone now contains no GSP parser jar at all. lib/ held two, gsqlparser-3.1.1.0 and gudusoft.gsqlparser-3.0.2.5, and they were doing real damage rather than just taking up space. pom_dlineage.xml pinned lib/gsqlparser-3.1.1.0.jar on system scope. This build has been documented as failing since before the demo trees were merged, on two "cannot find symbol" errors for setTraceTablePosition and generateColumnLevelLineageCsvSimple. The cause was the pinned jar, not the code: pointed at the same parser the root build resolves, it compiles, packages, and produces correct lineage XML. Verified by running the jar. connector/*/pom.xml pointed at ../../lib/gudusoft.gsqlparser-2.1.2.x.jar, files this repository has not contained for a long time. Now resolved from Maven like everything else. the .bat scripts setenv.bat put lib\ first on the classpath, so the 3.1.1.0 jar shadowed anything newer and compile_checksyntax.bat died on EOBTenantMode -- a symbol a current parser has. gudusoft.gsqlparser-3.0.2.5.jar referenced by nothing at all. So: both jars deleted, and every consumer resolves com.gudusoft:gsqlparser from Gudu's public repository. For the .bat workflow, which has no POM to resolve from, setenv.bat now bootstraps itself. When external_lib\ has no parser it calls the new setenv/fetch-parser.bat, which reads gsp.core.version out of pom.xml and does a mvn dependency:copy. Idempotent, and external_lib/ is gitignored. This does mean that route needs Maven once, which the README states plainly rather than keeping the old "Windows, no Maven" heading: one artifact resolved from one place beats a vendored copy that silently rots, which is exactly what happened here. windows-bat now covers four demos instead of one, chosen for the shapes the scripts come in: checksyntax (/f file /t vendor), formatsql (bare filename), listGSPInfo (no arguments), and modifysql, whose compile and run scripts are named differently (compile_modifysql.bat builds the folder, run_replaceTablename.bat runs one class). The job also asserts up front that no parser jar is committed, so vendoring one again fails CI. mvn clean test: 144 tests, the same 3 known analyzespTest failures. mvn -f pom_dlineage.xml package: builds, for the first time in this repository's recorded history. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_012qPRpoD8exYRrUmbfXXWXj
1 parent 1b59350 commit 4951c00

10 files changed

Lines changed: 220 additions & 97 deletions

File tree

‎.github/workflows/build.yml‎

Lines changed: 52 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -112,39 +112,63 @@ jobs:
112112
java-version: "8"
113113
cache: maven
114114

115-
# These scripts predate the parser being resolved from Maven. lib\ only
116-
# carries old parser jars now, so on its own compile_<demo>.bat fails on
117-
# symbols those jars predate. Drop the current parser into external_lib\,
118-
# which setenv.bat puts ahead of lib\ on the classpath for exactly this
119-
# reason. Not vendored: fetched here, and gitignored.
120-
- name: Fetch the parser into external_lib
121-
shell: bash
115+
# No parser jar is committed, so setenv.bat fetches one into external_lib\
116+
# on first use. This step only proves that bootstrap works from a clean
117+
# checkout; the demo steps below would trigger it anyway.
118+
- name: setenv.bat bootstraps the parser from Maven
119+
shell: cmd
122120
run: |
123-
set -euo pipefail
124-
ver=$(mvn -q help:evaluate -Dexpression=gsp.core.version -DforceStdout)
125-
echo "parser version: $ver"
126-
mvn -q dependency:copy \
127-
-Dartifact=com.gudusoft:gsqlparser:"$ver" \
128-
-DoutputDirectory=external_lib
129-
ls external_lib
121+
if exist external_lib\gsqlparser-*.jar (
122+
echo ::error::a parser jar is committed to this repository; it must be fetched, not vendored
123+
exit /b 1
124+
)
125+
call setenv\fetch-parser.bat
126+
dir external_lib
127+
for %%f in (external_lib\gsqlparser-*.jar) do exit /b 0
128+
echo ::error::fetch-parser.bat produced no parser jar
129+
exit /b 1
130130
131131
# `pause` at the end of each script would block forever on a runner with
132132
# no keyboard, so stdin is fed from NUL.
133-
- name: compile_checksyntax.bat then run_checksyntax.bat
133+
#
134+
# These four cover the shapes the scripts come in: a file+vendor demo, a
135+
# bare-filename demo, one that takes no arguments at all, and one nested a
136+
# directory deeper (so its cd depth differs). They are generated from one
137+
# template and go stale as a set, which is exactly what happened when the
138+
# demos moved directory, so this is a canary rather than full coverage.
139+
- name: Run the .bat scripts
134140
shell: cmd
135141
run: |
136-
cd src\main\java\gudusoft\gsqlparser\demos\checksyntax
137-
call compile_checksyntax.bat < NUL
138-
if not exist "%GITHUB_WORKSPACE%\build\gudusoft\gsqlparser\demos\checksyntax\checksyntax.class" (
139-
echo ::error::compile_checksyntax.bat did not produce checksyntax.class
140-
exit /b 1
142+
echo SELECT a.id FROM ta a; > "%GITHUB_WORKSPACE%\q.sql"
143+
144+
rem dir compile script run script args expected in output
145+
call :demo checksyntax checksyntax checksyntax "/f %GITHUB_WORKSPACE%\q.sql /t oracle" "syntax errors: 0" || exit /b 1
146+
call :demo formatsql formatsql formatsql "%GITHUB_WORKSPACE%\q.sql" "SELECT" || exit /b 1
147+
call :demo listGSPInfo listGSPInfo listGSPInfo "" "Supported DBs" || exit /b 1
148+
call :demo modifysql modifysql replaceTablename "" "output sql" || exit /b 1
149+
echo All .bat demos passed.
150+
exit /b 0
151+
152+
:demo
153+
setlocal
154+
set DEMO=%~1
155+
set CSCRIPT=%~2
156+
set RSCRIPT=%~3
157+
set ARGS=%~4
158+
set EXPECT=%~5
159+
echo.
160+
echo ==== %DEMO% : compile_%CSCRIPT%.bat / run_%RSCRIPT%.bat ====
161+
cd /d "%GITHUB_WORKSPACE%\src\main\java\gudusoft\gsqlparser\demos\%DEMO%"
162+
call compile_%CSCRIPT%.bat < NUL > "%GITHUB_WORKSPACE%\c.txt" 2>&1
163+
type "%GITHUB_WORKSPACE%\c.txt"
164+
findstr /i /c:"error" "%GITHUB_WORKSPACE%\c.txt" >NUL && (
165+
echo ::error::compile_%CSCRIPT%.bat reported an error
166+
endlocal & exit /b 1
141167
)
142-
cd /d "%GITHUB_WORKSPACE%"
143-
echo SELECT a.id FROM ta a; > q.sql
144-
cd src\main\java\gudusoft\gsqlparser\demos\checksyntax
145-
call run_checksyntax.bat /f "%GITHUB_WORKSPACE%\q.sql" /t oracle < NUL > "%GITHUB_WORKSPACE%\out.txt" 2>&1
146-
type "%GITHUB_WORKSPACE%\out.txt"
147-
findstr /c:"syntax errors: 0" "%GITHUB_WORKSPACE%\out.txt" >NUL || (
148-
echo ::error::run_checksyntax.bat did not report "syntax errors: 0"
149-
exit /b 1
168+
call run_%RSCRIPT%.bat %ARGS% < NUL > "%GITHUB_WORKSPACE%\r.txt" 2>&1
169+
type "%GITHUB_WORKSPACE%\r.txt"
170+
findstr /c:"%EXPECT%" "%GITHUB_WORKSPACE%\r.txt" >NUL || (
171+
echo ::error::run_%RSCRIPT%.bat did not print "%EXPECT%"
172+
endlocal & exit /b 1
150173
)
174+
endlocal & exit /b 0

‎README.md‎

Lines changed: 54 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -408,30 +408,36 @@ Everything else in those packages still builds. Reviving them needs an API
408408
migration against a build that includes the metadata layer, not just a
409409
recompile.
410410

411-
## The .bat scripts (Windows, no Maven)
411+
## The .bat scripts (Windows)
412412

413413
Each demo directory also ships `compile_<demo>.bat` and `run_<demo>.bat`, with
414-
`setenv/setenv.bat` holding the shared environment. The workflow:
415-
416-
1. **Put the parser in `external_lib/`.** From the repository root:
417-
```
418-
mvn dependency:copy -Dartifact=com.gudusoft:gsqlparser:4.1.6 -DoutputDirectory=external_lib
419-
```
420-
2. `cd` into a demo directory, e.g. `src\main\java\gudusoft\gsqlparser\demos\checksyntax`
421-
3. run `compile_checksyntax.bat`, then `run_checksyntax.bat`
422-
423-
You no longer have to edit `setenv.bat` for step 1 of the old instructions:
424-
it keeps whatever `JAVA_HOME` is already set and only falls back to a fixed path
425-
when there is none.
426-
427-
**`external_lib/` is not optional, and it must come before `lib/`.** These
428-
scripts predate the parser being resolved from Maven, and `lib/` now holds only
429-
*old* parser jars that other things still pin (`gsqlparser-3.1.1.0`,
430-
`gudusoft.gsqlparser-3.0.2.5`). With `lib/` first on the classpath those shadow
431-
the current parser and the demos fail to compile on symbols the old jars predate
432-
— `checksyntax` dies on `EOBTenantMode`. `setenv.bat` therefore puts
433-
`external_lib\*` ahead of `lib\*`, and `external_lib/` is gitignored so the
434-
parser is fetched rather than vendored.
414+
`setenv/setenv.bat` holding the shared environment.
415+
416+
```
417+
cd src\main\java\gudusoft\gsqlparser\demos\checksyntax
418+
compile_checksyntax.bat
419+
run_checksyntax.bat /f ..\..\..\..\..\..\..\q.sql /t oracle
420+
```
421+
422+
That is the whole workflow now. You no longer edit `setenv.bat` first: it keeps
423+
whatever `JAVA_HOME` is already set, and it fetches the parser for you.
424+
425+
**No parser jar is committed to this repository**, so the first script you run
426+
pulls one down. `setenv.bat` calls `setenv/fetch-parser.bat`, which reads
427+
`gsp.core.version` out of `pom.xml` and does a `mvn dependency:copy` into
428+
`external_lib/`. It is a no-op once the jar is there, and `external_lib/` is
429+
gitignored.
430+
431+
That means the `.bat` route needs Maven **once**, to fetch, and never again.
432+
That is a deliberate trade. Vendoring a parser under `lib/` is what let these
433+
scripts quietly compile against a build years older than their own source: the
434+
jar in `lib/` was 3.1.1.0 while the demos had moved on to APIs like
435+
`EOBTenantMode`, so `compile_checksyntax.bat` failed on a symbol that a current
436+
parser has. One artifact, resolved from one place, is worth a one-time Maven
437+
call.
438+
439+
`external_lib/` also comes before `lib/` on the classpath, so the fetched parser
440+
wins over anything dropped into `lib/` later.
435441

436442
### These are now tested on Windows
437443

@@ -440,15 +446,24 @@ They had been stale for years — compiling `src\main\java\demos\<demo>\` and
440446
`gudusoft/gsqlparser/demos/`. Nothing noticed, because nothing ran them.
441447

442448
The `windows-bat` job in `.github/workflows/build.yml` now does, on
443-
`windows-latest`: it fetches the parser into `external_lib/`, runs
444-
`compile_checksyntax.bat`, asserts the `.class` file appears, runs
445-
`run_checksyntax.bat`, and asserts it reports `syntax errors: 0`. Each script
446-
ends with `pause`, so CI feeds their stdin from `NUL` to keep them from blocking
447-
on a runner with no keyboard.
449+
`windows-latest`. It first asserts that **no parser jar is committed** and that
450+
`fetch-parser.bat` can bootstrap one, then compiles and runs four demos, each
451+
checked against a string its output must contain:
452+
453+
| demo | shape it covers |
454+
|------|-----------------|
455+
| `checksyntax` | `/f <file> /t <vendor>` |
456+
| `formatsql` | bare filename |
457+
| `listGSPInfo` | no arguments at all |
458+
| `modifysql` | compile and run scripts named differently (`compile_modifysql.bat` builds the folder, `run_replaceTablename.bat` runs one class) |
459+
460+
Each script ends with `pause`, so CI feeds their stdin from `NUL` to keep them
461+
from blocking on a runner with no keyboard.
448462

449-
That covers one demo, not all 45. It is enough to catch the failure mode that
450-
actually happened here — the whole family going stale together after a
451-
directory move — since they are generated from one template and break as a set.
463+
Four demos, not all 45, is a deliberate stopping point: they are generated from
464+
one template and go stale as a set, which is exactly what happened when the
465+
demos moved directory. The four cover the distinct argument shapes, so a change
466+
that breaks the template shows up here.
452467

453468

454469
## Building the dlineage demo on its own
@@ -459,7 +474,7 @@ standalone lineage tool:
459474
```bash
460475
mvn -f pom_dlineage.xml package
461476

462-
java -cp "target-dlineage/gsp_demo_java_dlineage-1.0-SNAPSHOT.jar:lib/*" \
477+
java -cp "target-dlineage/gsp_demo_java_dlineage-1.0-SNAPSHOT.jar:external_lib/*:lib/*" \
463478
gudusoft.gsqlparser.demos.dlineage.DataFlowAnalyzer \
464479
/f demo.sql /o lineage.json /json /graph \
465480
/simpleShowRelationTypes fdd,fdr /filterRelationTypes fdd
@@ -474,15 +489,16 @@ rather than the root build's `target/`. It shares this repository's
474489
without a separate output directory the compiler plugin's incremental-build
475490
cleanup would delete every `.class` file the root build produced that isn't
476491
part of this smaller source set — wiping out a working root build before this
477-
one even reaches its own compile error below. See
492+
one even reaches its own build. See
478493
[#39](https://github.com/sqlparser/gsp_demo_java/issues/39).
479494

480-
> **This build currently fails**, and did so before the trees were merged. It
481-
> pins `lib/gsqlparser-3.1.1.0.jar`, but `DataFlowAnalyzer` has moved on and now
482-
> calls `getOption().setTraceTablePosition(...)` and
483-
> `ProcessUtility.generateColumnLevelLineageCsvSimple(...)`, neither of which
484-
> that jar has. It needs a parser build carrying both those methods and the
485-
> metadata layer. Recorded here so the invocations above are not lost.
495+
**This build used to fail**, and had done since before the demo trees were
496+
merged. The cause was the pinned jar, not the code: `pom_dlineage.xml` declared
497+
`lib/gsqlparser-3.1.1.0.jar` on `system` scope, while `DataFlowAnalyzer` had
498+
moved on to `getOption().setTraceTablePosition(...)` and
499+
`ProcessUtility.generateColumnLevelLineageCsvSimple(...)`, neither of which a
500+
3.1.1.0 jar has. It now resolves the same parser the root build does, and
501+
builds and runs.
486502

487503
## master and dev branches
488504

‎connector/oracleConnector/pom.xml‎

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -17,13 +17,21 @@
1717
<maven.compiler.target>1.6</maven.compiler.target>
1818
</properties>
1919

20+
<repositories>
21+
<repository>
22+
<id>gudu-public-releases</id>
23+
<url>https://www.sqlparser.com/maven/</url>
24+
</repository>
25+
</repositories>
26+
2027
<dependencies>
28+
<!-- The parser is resolved from Gudu's public Maven repository. It used to
29+
point at ../../lib/gudusoft.gsqlparser-2.1.2.x.jar, a file this
30+
repository has not contained for a long time. -->
2131
<dependency>
22-
<groupId>com.sqlparser</groupId>
23-
<artifactId>gsp</artifactId>
24-
<version>2.1.2.2</version>
25-
<scope>system</scope>
26-
<systemPath>${project.basedir}/../../lib/gudusoft.gsqlparser-2.1.2.2.jar</systemPath>
32+
<groupId>com.gudusoft</groupId>
33+
<artifactId>gsqlparser</artifactId>
34+
<version>4.1.6</version>
2735
</dependency>
2836
<dependency>
2937
<groupId>com</groupId>

‎connector/snowflakeConnector/pom.xml‎

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -17,13 +17,21 @@
1717
<maven.compiler.target>1.6</maven.compiler.target>
1818
</properties>
1919

20+
<repositories>
21+
<repository>
22+
<id>gudu-public-releases</id>
23+
<url>https://www.sqlparser.com/maven/</url>
24+
</repository>
25+
</repositories>
26+
2027
<dependencies>
28+
<!-- The parser is resolved from Gudu's public Maven repository. It used to
29+
point at ../../lib/gudusoft.gsqlparser-2.1.2.x.jar, a file this
30+
repository has not contained for a long time. -->
2131
<dependency>
22-
<groupId>com.sqlparser</groupId>
23-
<artifactId>gsp</artifactId>
24-
<version>2.1.2.8</version>
25-
<scope>system</scope>
26-
<systemPath>${project.basedir}/../../lib/gudusoft.gsqlparser-2.1.2.8.jar</systemPath>
32+
<groupId>com.gudusoft</groupId>
33+
<artifactId>gsqlparser</artifactId>
34+
<version>4.1.6</version>
2735
</dependency>
2836
<!-- Resolved from Maven Central rather than a jar you drop into lib/.
2937
3.12.9 was named here before, which Dependabot flagged for six

‎connector/sqlServerConnector/pom.xml‎

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -17,13 +17,21 @@
1717
<maven.compiler.target>1.6</maven.compiler.target>
1818
</properties>
1919

20+
<repositories>
21+
<repository>
22+
<id>gudu-public-releases</id>
23+
<url>https://www.sqlparser.com/maven/</url>
24+
</repository>
25+
</repositories>
26+
2027
<dependencies>
28+
<!-- The parser is resolved from Gudu's public Maven repository. It used to
29+
point at ../../lib/gudusoft.gsqlparser-2.1.2.x.jar, a file this
30+
repository has not contained for a long time. -->
2131
<dependency>
22-
<groupId>com.sqlparser</groupId>
23-
<artifactId>gsp</artifactId>
24-
<version>2.1.2.2</version>
25-
<scope>system</scope>
26-
<systemPath>${project.basedir}/../../lib/gudusoft.gsqlparser-2.1.2.2.jar</systemPath>
32+
<groupId>com.gudusoft</groupId>
33+
<artifactId>gsqlparser</artifactId>
34+
<version>4.1.6</version>
2735
</dependency>
2836
<dependency>
2937
<groupId>com.microsoft.sqlserver</groupId>

‎lib/gsqlparser-3.1.1.0.jar‎

-11 MB
Binary file not shown.
-10.5 MB
Binary file not shown.

‎pom_dlineage.xml‎

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,18 @@
2323
<maven.compiler.source>1.8</maven.compiler.source>
2424
<maven.compiler.target>1.8</maven.compiler.target>
2525
<maven.test.skip>true</maven.test.skip>
26+
<gsp.core.version>4.1.6</gsp.core.version>
2627
</properties>
2728

29+
<!-- The parser is not on Maven Central; it comes from Gudu's public
30+
repository, same as the root pom.xml. Nothing is vendored under lib/. -->
31+
<repositories>
32+
<repository>
33+
<id>gudu-public-releases</id>
34+
<url>https://www.sqlparser.com/maven/</url>
35+
</repository>
36+
</repositories>
37+
2838
<dependencies>
2939
<dependency>
3040
<groupId>junit</groupId>
@@ -34,11 +44,9 @@
3444
</dependency>
3545

3646
<dependency>
37-
<groupId>gudusoft</groupId>
47+
<groupId>com.gudusoft</groupId>
3848
<artifactId>gsqlparser</artifactId>
39-
<version>3.1.1.0</version>
40-
<scope>system</scope>
41-
<systemPath>${project.basedir}/lib/gsqlparser-3.1.1.0.jar</systemPath>
49+
<version>${gsp.core.version}</version>
4250
</dependency>
4351

4452
<dependency>

‎setenv/fetch-parser.bat‎

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
@echo off
2+
REM # Fetches the General SQL Parser jar into external_lib\.
3+
REM #
4+
REM # No parser jar is committed to this repository. A fresh clone has none, by
5+
REM # design: the parser is a released artifact resolved from Gudu's public Maven
6+
REM # repository, and vendoring a copy is how this repository previously ended up
7+
REM # compiling demos against a build years older than their source.
8+
REM #
9+
REM # Called automatically by setenv\setenv.bat when external_lib\ has no parser,
10+
REM # so the compile_<demo>.bat / run_<demo>.bat scripts work on a fresh clone.
11+
REM # Safe to run directly, and a no-op once the jar is there.
12+
REM #
13+
REM # Requires Maven on PATH, once. After that the .bat workflow needs nothing.
14+
15+
setlocal
16+
17+
REM # Run from the repository root regardless of where this was invoked from.
18+
cd /d "%~dp0.."
19+
20+
for %%f in (external_lib\gsqlparser-*.jar) do (
21+
echo Parser already present: %%f
22+
endlocal
23+
exit /b 0
24+
)
25+
26+
REM # Single source of truth for the version: gsp.core.version in pom.xml.
27+
for /f "delims=" %%v in ('mvn -q help:evaluate -Dexpression^=gsp.core.version -DforceStdout 2^>nul') do set GSPVER=%%v
28+
29+
if "%GSPVER%"=="" (
30+
echo.
31+
echo ***************************
32+
echo Could not read gsp.core.version from pom.xml.
33+
echo Is Maven on your PATH? The parser has to be fetched once:
34+
echo mvn dependency:copy -Dartifact=com.gudusoft:gsqlparser:VERSION -DoutputDirectory=external_lib
35+
echo ***************************
36+
echo.
37+
endlocal
38+
exit /b 1
39+
)
40+
41+
echo Fetching parser %GSPVER% into external_lib\ ...
42+
call mvn -q dependency:copy -Dartifact=com.gudusoft:gsqlparser:%GSPVER% -DoutputDirectory=external_lib
43+
if errorlevel 1 (
44+
echo Failed to fetch the parser. See the message above.
45+
endlocal
46+
exit /b 1
47+
)
48+
49+
echo Done.
50+
endlocal
51+
exit /b 0

0 commit comments

Comments
 (0)