1515import org .junit .jupiter .api .Timeout ;
1616
1717import java .util .logging .Logger ;
18+ import java .util .Arrays ;
19+ import java .util .concurrent .TimeUnit ;
1820
1921import static net .sf .jsqlparser .test .TestUtils .assertSqlCanBeParsedAndDeparsed ;
2022import org .junit .jupiter .api .Assertions ;
@@ -139,22 +141,23 @@ public void testRecursiveBracketExpressionIssue1019_2() throws JSQLParserExcepti
139141 doIncreaseOfParseTimeTesting ("IF(1=1, $1, 2)" , "1" , 20 );
140142 }
141143
142- @ Test void testIssue2422 () throws JSQLParserException {
144+ @ Test
145+ void testIssue2422 () throws JSQLParserException {
143146 String sqlStr =
144147 "SELECT\n "
145- + "\t \t \t \t ((((position('-' IN (\n "
146- + "\t \t \t \t CASE WHEN ((\n "
147- + "\t \t \t \t CASE WHEN (5 < 0) THEN\n "
148- + "\t \t \t \t 'yes'\n "
149- + "\t \t \t \t ELSE\n "
150- + "\t \t \t \t 'no'\n "
151- + "\t \t \t \t END) = 'yes') THEN\n "
152- + "\t \t \t \t SUBSTRING('2012-january-18', (((LENGTH('2012-january-18')) + (5)) + (1)), ABS((0) - (5)))\n "
153- + "\t \t \t \t ELSE\n "
154- + "\t \t \t \t SUBSTRING('2012-january-18', ((5) + (1)))\n "
155- + "\t \t \t \t END)) - 1) + (1)) - (5)) + (0))\n "
156- + "\t \t \t \t FROM\n "
157- + "\t \t \t \t testtable" ;
148+ + "\t \t \t \t ((((position('-' IN (\n "
149+ + "\t \t \t \t CASE WHEN ((\n "
150+ + "\t \t \t \t CASE WHEN (5 < 0) THEN\n "
151+ + "\t \t \t \t 'yes'\n "
152+ + "\t \t \t \t ELSE\n "
153+ + "\t \t \t \t 'no'\n "
154+ + "\t \t \t \t END) = 'yes') THEN\n "
155+ + "\t \t \t \t SUBSTRING('2012-january-18', (((LENGTH('2012-january-18')) + (5)) + (1)), ABS((0) - (5)))\n "
156+ + "\t \t \t \t ELSE\n "
157+ + "\t \t \t \t SUBSTRING('2012-january-18', ((5) + (1)))\n "
158+ + "\t \t \t \t END)) - 1) + (1)) - (5)) + (0))\n "
159+ + "\t \t \t \t FROM\n "
160+ + "\t \t \t \t testtable" ;
158161 assertSqlCanBeParsedAndDeparsed (sqlStr );
159162 }
160163
@@ -204,18 +207,17 @@ public void testIncreaseOfParseTime() throws JSQLParserException {
204207
205208 private void doIncreaseOfParseTimeTesting (String template , String finalExpression , int maxDepth )
206209 throws JSQLParserException {
207- long oldDurationTime = 2000 ;
210+ long oldDurationTime = TimeUnit . SECONDS . toNanos ( 2 ) ;
208211 int countProblematic = 0 ;
209212 for (int i = 0 ; i < maxDepth ; i ++) {
210213 String sql = "SELECT " + buildRecursiveBracketExpression (template , finalExpression , i )
211214 + " FROM mytbl" ;
212- long startTime = System .currentTimeMillis ();
213- assertSqlCanBeParsedAndDeparsed (sql , true , parser -> parser .withTimeOut (12000 ));
214- long durationTime = System .currentTimeMillis () - startTime ;
215+ long durationTime = medianParseDuration (sql );
215216
216217 if (i > 0 ) {
217- System .out .println ("old duration " + oldDurationTime + " new duration time "
218- + durationTime + " for " + sql );
218+ System .out .println ("old duration " + TimeUnit .NANOSECONDS .toMicros (oldDurationTime )
219+ + " us, new duration " + TimeUnit .NANOSECONDS .toMicros (durationTime )
220+ + " us for " + sql );
219221 }
220222 if (oldDurationTime * 10 < durationTime ) {
221223 countProblematic ++;
@@ -228,6 +230,19 @@ private void doIncreaseOfParseTimeTesting(String template, String finalExpressio
228230 }
229231 }
230232
233+ private long medianParseDuration (String sql ) throws JSQLParserException {
234+ // A single millisecond sample can turn scheduler or GC jitter into a tenfold increase.
235+ // Keep the growth limit, but compare representative durations from a monotonic clock.
236+ long [] durations = new long [5 ];
237+ for (int sample = 0 ; sample < durations .length ; sample ++) {
238+ long startTime = System .nanoTime ();
239+ assertSqlCanBeParsedAndDeparsed (sql , true , parser -> parser .withTimeOut (12000 ));
240+ durations [sample ] = System .nanoTime () - startTime ;
241+ }
242+ Arrays .sort (durations );
243+ return durations [durations .length / 2 ];
244+ }
245+
231246 @ Test
232247 @ Timeout (2000 )
233248 public void testRecursiveBracketExpression () {
@@ -552,8 +567,7 @@ JSQLParserException.class, new Executable() {
552567 public void execute () throws Throwable {
553568 TestUtils .assertSqlCanBeParsedAndDeparsed (sqlStr , true );
554569 }
555- }
556- );
570+ });
557571 }
558572
559573 @ Test
@@ -566,8 +580,7 @@ JSQLParserException.class, new Executable() {
566580 public void execute () throws Throwable {
567581 TestUtils .assertSqlCanBeParsedAndDeparsed (sqlStr , true );
568582 }
569- }
570- );
583+ });
571584 }
572585
573586 @ Test
0 commit comments