Skip to content

[BUG] JSQLParser 5.4-SNAPSHOT : performance.sql contains unparseable @Prompt macros; parseStatements used to hide this by returning null (JSQLParserBenchmark measured incomplete parses) #2599

Description

@fudianchn

AI disclosure: this issue was prepared with AI coding agents, reviewed and revised line by line by me.

Correction (2026-09-11, same day): the original report below described this as a regression introduced between 6c726d8 and current master ("the corpus parsed fine on 6c726d8"). That was wrong: my probe back then did not check the return value of parseStatements, and on 6c726d8 it silently returns null for this corpus (the exact bug reported in #2576), which my probe misread as success. The statement with the @Prompt macros fails to parse on both commits at the same position. The only real change is that #2568 / #2594 fixed the silent null, so the long-standing corpus damage is now visible. The original text is kept below with the wrong claim struck through.

Failing SQL Feature:

  • src/test/resources/net/sf/jsqlparser/performance.sql contains BusinessObjects @Prompt(...) macros that JSQLParser cannot parse (and, as far as I can tell, never could: the statement fails at the same position on 6c726d8 and on current master, standalone or as part of the file).
  • Until Fix parseStatements failure propagation and executor cleanup #2568 / Align empty input handling for statement parsing #2594 this was invisible: parseStatements silently returned null when a statement failed. As a consequence JSQLParserBenchmark.parseSQLStatements produced timing numbers while the corpus was not fully parsed (the null result was simply consumed). With the fix, the benchmark now correctly fails fast with the ParseException below.
  • Open questions for the maintainers: should the benchmark assert corpus integrity (non-null result, expected statement count) so incomplete-parse timings cannot happen silently, and should the @Prompt statement be repaired or supported?

SQL Example:

Excerpt of the failing spot (corpus line 497):

SELECT ... FROM ... WHERE ( COALESCE(CLM.WORKFLOW_C,0) IN @Prompt(P_WorkflowTypeInclude)
  AND COALESCE(CLM_TRAIT_4.NAME,'CCA') IN @Prompt(P_CCA-TPMG) ... )
net.sf.jsqlparser.parser.ParseException: Encountered: <OPENING_BRACKET> / "(", at line 497, column 40, in lexical state DEFAULT.

Repro on both commits (statement alone, corpus lines 196-1688):

CCJSqlParserUtil.parse(content); // 6c726d8: THROWS at 302:40; 7cc86386: THROWS at 302:40 (same position)
CCJSqlParserUtil.parseStatements(corpus); // 6c726d8: returns null silently; 7cc86386: throws JSQLParserException

Software Information:

  • JSqlParser version: 5.4-SNAPSHOT (master 7cc86386; same parse failure on 6c726d8)
  • Database: Oracle (BusinessObjects @Prompt macros)

Tips:

  • Standalone forms such as x IN @Prompt(p1) or SELECT @f(1) fail on both commits; the corpus statement is the only place this surfaces in the repo.
  • The timing impact is real but predates the current master: on 6c726d8 the JMH score described an incomplete parse of the corpus.

Activity

  1. changed the title [-][BUG] JSQLParser 5.4-SNAPSHOT : benchmark corpus no longer parses (IN @Prompt(...)), JSQLParserBenchmark fails on master[/-] [+][BUG] JSQLParser 5.4-SNAPSHOT : performance.sql contains unparseable @Prompt macros; parseStatements used to hide this by returning null (JSQLParserBenchmark measured incomplete parses)[/+] on Sep 11, 2026
  2. fudianchn commented on Sep 11, 2026

    @fudianchn
    ContributorAuthor

    Correction after re-verifying with a probe that checks the return value: the corpus statement with the @Prompt macros fails at the same position on both 6c726d8 and current master. The only change is that #2568 / #2594 replaced the silent null return of parseStatements with a proper exception, so the benchmark now fails instead of silently timing an incomplete parse. Title and description are updated accordingly.

  3. manticore-projects commented on Sep 11, 2026

    @manticore-projects
    Contributor

    Thank you for bisecting this, in my opinion we should go this route: "should the @prompt statement be repaired".

  4. manticore-projects commented on Sep 11, 2026

    @manticore-projects
    Contributor

    Thank you, fixed -- with interesting outcome:

    Benchmark                                     (version)  Mode  Cnt    Score    Error  Units
    JSQLParserBenchmark.parseSQLStatements           latest  avgt   15   32.135 ±  0.820  ms/op
    JSQLParserBenchmark.parseSQLStatements              5.3  avgt   15  965.707 ± 15.947  ms/op
    JSQLParserBenchmark.parseSQLStatements              5.1  avgt   15  314.454 ±  3.717  ms/op
    
  5. added a commit that references this issue on Sep 11, 2026
    df984dc
  6. fudianchn commented on Sep 12, 2026

    @fudianchn
    ContributorAuthor

    The 5.1 and 5.3 numbers measure incomplete parses and cannot be compared with latest: both versions still return null silently from parseStatements when a statement fails (#2576), and the repaired corpus still fails on them.

    1. Per-version result on the repaired corpus (null/size-checked, 40 warmup rounds, median of 30, same host):
      • 5.1: null after 283 ms (3 statements fail, incl. the trailing WITH)
      • 5.2: complete, 54 statements, 619 ms
      • 5.3: null after 1089 ms (2 statements fail)
      • master c7f8ff89: complete, 54 statements, ~35 ms (consistent with the 32.1 above)
    2. On 5.3 the ~80 KB statement at line 194 fails with TimeoutException: that is the super-linear lookahead from [BUG] Parse time grows super-linearly on long dotted-name chains and nested parentheses (phase-2 lookahead), StackOverflowError at nesting depth ~2000 #2519. 5.2 parses it fine, so the cliff landed between 5.2 and 5.3, not gradually.
    3. The comparable pair is 5.2 vs master: 619 ms -> ~35 ms (~18x), mostly fix: memoize long-chain predicate walks behind a size threshold #2520 (memoized long-chain predicate walks); 5.2 barely moves between cold and warm runs because the cliff dominates its profile.
    4. The benchmark could assert non-null and the expected statement count per version, so truncated timings cannot pass as results: this is also what had hidden the corpus damage for years.
  7. manticore-projects commented on Sep 12, 2026

    @manticore-projects
    Contributor

    Thank you, noted, but almost irrelevant now:

    1. we got way faster
    2. and we got way more feature complete and correct

    The fact, that there is even more story to tell about the details does not matter for most of the users.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions